Наличие внешнего ключа в таблице user
, которое является необязательным, чтобы избежать взаимозависимости, которая препятствует добавлению записей в любую из них, вероятно, является более чистым решением. Это избавляет от необходимости иметь дело с предотвращением множественных основных адресов для пользователя, занимает меньше места и делает объединения, чтобы использовать информацию об основном адресе немного проще.
Уникальность встроенного в внешний ключ дизайна. При использовании конструкции is_main простейшим предупреждением является создание поля 1 или нуля (вместо 1 или 0) и добавление составного уникального ключа (user_id, is_main); и затем, чтобы изменить значение по умолчанию, вы должны были бы обнулить старое значение по умолчанию, прежде чем установить новое в 1.
Поле внешнего ключа занимает примерно 4 байта (при условии int pk для адресов и игнорирования обнуляемости); is_main занимает по крайней мере 1 байт для каждого адреса, который может иметь пользователь ... если есть другие битовые поля, он может быть меньше, но проблемы с пространством действительно тривиальны.
Чтобы получить пользователя с адресом по умолчанию:
SELECT *
FROM user AS u
LEFT JOIN address AS a
ON u.main_address_id = a.address_id
WHERE u.user_id = ?
;
против
SELECT *
FROM users AS u
LEFT JOIN address AS a
ON u.user_id = a.user_id
AND a.is_main = 1
WHERE u.user_id = ?
;
... что AND is_main = 1
может показаться тривиальной вещью, и во многих случаях это будет так, но в более сложном запросе это такая вещь, которая может означать, что не нужно брать индекс.
Тем не менее, положительная сторона дизайна is_main: если у вас уже есть user_id, но не main_address_id, вы можете получить информацию об основном адресе простым выбором (без объединения) только из таблицы адресов.