Установка основной строки в отношении один ко многим
В некоторых случаях у вас может быть строка по умолчанию или основная строка с one to many
отношения. Который определяется по столбцу, как primary
, И если вы измените основной ряд, вы установите тот, который вы хотите 1
и другие, чтобы 0
;
Вот пример, показывающий мой подход к решению этой проблемы с помощью Yii2
,
Пример: у нас есть две таблицы User
а также UserAddress
Это функция в UserAddress
учебный класс. Это работа, чтобы сделать текущий UserAddress
в качестве основного адреса для User
,
public function makePrimary() {
$addresses = $this -> getUser() -> getUserAddresses() -> all();
foreach ( $addresses As $address ) {
$address -> is_primary = 0;
$address -> save();
}
$this -> is_primary = 1;
$this -> save();
}
Теперь мой вопрос, это хороший подход, который вы обычно делаете? Если нет, можете ли вы предложить лучший подход для достижения того же результата?
2 ответа
Благодаря Balaji Viswanath
, Его ответ напоминает мне другое решение, которое может достичь того же. Но я думаю, что лучше.
Вот код (Функции находятся внутри UserAddress
модельный класс)
public function makePrimary() {
self::updateAll(['is_primary' => 0], 'is_primary=1 AND user_ID=' . $this -> user_ID);
// or just
// self::updateAll(['is_primary' => 0], 'user_ID=' . $this -> user_ID);
$this -> is_primary = 1;
$this -> save();
}
С вышеупомянутым решением. Я полагаю, что достиг той же цели с помощью только 2 запросов Balaji Viswanath
делает с решением, которое он придумал.
При вашем подходе производительность имеет большое значение, так как чем больше число строк адресов, тем больше нагрузка на сервер.
Предположим, у вас есть 50 адресных строк для одного пользователя. Согласно вашему коду выполнение запроса выглядит следующим образом
- выполнить запрос для получения пользовательской записи при вызове $this->getUser()
- выполнить запрос для получения адресов пользователей при вызове getUserAddresses()->all()
- перебрать все 50 строк адреса и выполнить 50 запросов на обновление, чтобы установить для is_primary значение 0
- выполнить запрос для сохранения текущей выбранной строки как is_primary = 1
Таким образом, в общей сложности база данных MySQL запрашивалась около 53 раз.
Но рассмотрим следующий подход. Я предполагаю, что getUser () связан с getUserAddresses () через "user_id", а имя таблицы адресов - "user_addresses"
public function makePrimary() {
\Yii::$app->db->createCommand()->update('user_addresses', array(
'is_primary'=>0,
), 'user_id=:id', array(':id'=>$this->user_id)); //Set is_primary as 0 for all addresses in one go
$this -> is_primary = 1;
$this -> save();
}
Здесь вы можете обновить is_primary как 0 для всех строк, используя один запрос на обновление. Таким образом, всего вы использовали 2 запроса для выполнения задачи