Предисловие
Каждая начинающая программная обезьяна столкнется с некоторыми странными и странными проблемами, например, в случае двух или более таблиц отношений данных необходимо запросить данные соответствующих таблиц отношений с помощью одной основной таблицы, как показано в следующей таблице отношений
Приготовиться
Описание технического паспорта
- Таблица пользователей
- Форма членской карточки (VIP)
- VIP u поля
Сценарии использования
- Вы можете использовать требования к интерфейсу, необходимые для запроса соответствующих полей нескольких таблиц в списке
требование
- Список членских карточек
- Необходимо иметь ник участника/аватар/имя/пол адрес электронной почты/идентификатор участника
Осуществление
- В соответствии с (членская карточка), узнайте информацию о пользователе-участнике и прилагаемые табличные данные членской карточки для связи. Есть два примера
Пример 1
- Результат операции
[ { "vip_id": 1, "user_id": 1, "user": { "user_id": 1, "Nickname": "little white", "avatar": "http://xiaobai.png" }, "fields": { "vip_id": 1, "RealName": "little white", "sex": 1, "email": "[email protected]" } }, { "vip_id": 2, "user_id": 2, "user": { "user_id": 2, "Nickname": "millet", "avatar": "http://xiaobai.png" }, "fields": { "vip_id": 2, "RealName": "millet", "sex": 1, "email": "[email protected]" } } ]
Пример 2
offset(0)->limit(10)->asArray()->all(); // user ID $userIds = array_unique(array_column($vips,'user_id')); //Membership ID $vipIds = array_unique(array_column($vips,'vip_id')); //Membership card user information data list $users = User::find()->andWhere(['user_id'=>$userIds])->asArray()->limit(count($userIds))->all(); //The user ID is the key to reorganize the membership card information data $usersRow = array_column($users,null,'user_id'); //Membership card schedule data list $fields = VipFields::find()->andWhere(['vip_id'=>$vipIds])->asArray()->limit(count($vipIds))->all(); //The data of the attached table of the restructured membership card takes VIP Ou ID as the key $fieldsRow = array_column($fields,null,'vip_id'); foreach($vips as &$row){ //Assembly membership card user information does not exist is null $row['user'] = $usersRow[$row['user_id']] ?? null; //Assembly membership card attachment information does not exist is null $row['fields'] = $fieldsRow[$row['vip']] ?? null; } return $vips; ?>
- Результат операции
[ { "vip_id": 1, "user_id": 1, "user": { "user_id": 1, "Nickname": "little white", "avatar": "http://xiaobai.png" }, "fields": { "vip_id": 1, "RealName": "little white", "sex": 1, "email": "[email protected]" } }, { "vip_id": 2, "user_id": 2, "user": { "user_id": 2, "Nickname": "millet", "avatar": "http://xiaobai.png" }, "fields": { "vip_id": 2, "RealName": "millet", "sex": 1, "email": "[email protected]" } } ]
Использование соединения Yii с()
Официальное заявление
- Этот метод позволит вам повторно использовать существующие определения ассоциаций для выполнения запросов на объединение. Основываясь на определении указанной связи, метод добавляет один или несколько операторов соединения к текущему
- Если параметр загрузки $eager равен true, метод также выполняет немедленную загрузку указанной ассоциации, что эквивалентно вызову with() с указанной ассоциацией.
Обратите внимание, что, поскольку запрос на объединение будет выполнен, вам необходимо устранить неоднозначность имен столбцов.
- Этот метод отличается от with() тем, что он создает и выполняет инструкцию join SQL для основной таблицы. И когда значение $eager loading равно true, в дополнение к указанию связи вызывается функция with ().
Определение
- При объявлении связи в классе Yii \ DB \ activerecord используйте этот метод, чтобы указать таблицу соединений следующим образом:
//Designated connection membership card schedule public function getFields() { return $this->hasOne(VipFields::class,['vip_id'=>'vip_id']); } //User list of designated connection membership card public function getUser() { return $this->hasOne(User::class,['user_id'=>'user_id']); }
Обратите внимание на следующее:
1. When the table name has an underscore, the first letter of the table name in joinwith should be lowercase, and the first letter after the underscore should be uppercase 2. When there is a where condition, the table name in front of the field name. For some cross database names, the database name should be full.
Воспользуйся
- Как используется в приведенном выше сценарии требований
Когда для подключения VIP-модели используется соединение с, а модели полей и пользователей используются одновременно, это означает, что VIP используется в качестве основной таблицы, vip_fields и таблицы пользователей используются в качестве присоединенных таблиц, и результаты запроса могут быть получены только при наличии связанных данных в трех таблицах
-Operation results
[ { "vip_id": 1, "user_id": 1, "user": { "user_id": 1, "Nickname": "little white", "avatar": "http://xiaobai.png" }, "fields": { "vip_id": 1, "RealName": "little white", "sex": 1, "email": "[email protected]" } }, { "vip_id": 2, "user_id": 2, "user": { "user_id": 2, "Nickname": "millet", "avatar": "http://xiaobai.png" }, "fields": { "vip_id": 2, "RealName": "millet", "sex": 1, "email": "[email protected]" } } ]
отчет о событиях, произошедших после рассказываемого события
- Пример 1 запрос данных в foreach приводит к частым запросам к базе данных, что приводит к высокой нагрузке на базу данных и 1 + (n * 2) запросам к базе данных, что оказывает большое влияние на базу данных
- Пример 2 после запроса основной таблицы членской карточки идентификатор ассоциации таблицы ассоциаций выводится отдельно в виде массива, а затем выполняется пакет запросов списка и реорганизаций. Количество запросов к базе данных увеличивается в 3 раза
резюме
Различные требования имеют различную логику обработки кода. Возьмем, к примеру, пример 1 и пример 2. Хотя пример 1 также может соответствовать требованиям к интерфейсу, он оказывает большое влияние на базу данных и не рекомендуется использовать. Пример 1 содержит множество этапов обработки, но оказывает небольшое влияние на данные. Вы можете выбрать пример 2 для использования. Если вы найдете лучшее решение, вы продолжите оптимизацию