Это зависит от того, является ли отношение «человек к адресу» равным нулю или плюс к одному.
Если у человека требуется первичный адрес, я бы поместил его в таблицу Persons
(так как это обязательный атрибут).
В другой стороны, если человек может существовать в вашей схеме без адреса, я хотел бы оставить все адреса в Addresses
таблице как равного и использовать атрибут Persons
таблицы для выбора первичного (или NULL или указатель на соответствующую строку Addresses
).
Если вы сохраняете примитивность адреса в таблице Addresses
, что вы будете делать, если два адреса для Боба Смита утверждают, что они являются первичными? Вы можете остановить это с помощью триггеров, но гораздо эффективнее правильно разработать схему.
И, если у двух соседей по одному адресу, но каждый живет там все время, а другой проводит большую часть своего времени, обманутого своей девушкой, что происходит потом? Если primality находится в таблице Addresses, вы не сможете использовать адресные строки между людьми.
То, что я пытаюсь понять, заключается в том, что вам нужно выделить свои атрибуты для правильных объектов. Основной адрес лица принадлежит человеку, а не адресу.
Для достижения максимальной эффективности и гибкости, я бы следующая схема:
Persons:
Id primary key
PrimaryAddressId
OtherStuff
Addresses:
Id primary key
OtherStuff
PersonAddresses:
Id primary key
PersonId foreign key on Persons(Id)
AddressId foreign key on Addresses(Id)
Вы иметь незначительные проблемы целостности данных, Persons.PrimaryAddressId
может быть указателем повешения. Вы не можете сделать его внешним ключом к одному из основных ключей, так как вы хотите, чтобы он разрешил NULL
. Это означает, что вам нужно будет учесть возможность того, что он может указывать на несуществующий Addresses.Id
.
Я бы просто исправить это как триггер before-delete на Addresses
, чтобы обновить соответствующие строки Persons
(установка PrimaryAddressid
в NULL).
Или вы могли бы быть хитрыми и один адрес «Unknown» в Addresses
столе так, чтобы каждая строка в Persons
имеет по крайней мере один адрес (те, чьи основной адрес неизвестен автоматически получают PrimaryAddressid
набор на «Unknown» адрес строка.
Тогда вы могли бы сделать его надлежащее отношение с ограничениями и упростить SQL несколько. Прагматизм часто побеждает догматизм в реальном мире :-)
Не могли бы вы использовать этот дизайн, если отношение Person-> Addresses было привязано к одному-ко-многим, в отличие от мужчины-ко-многим, которое это разрешает? В этом случае иногда могут возникать дубликаты адресов, но, например, в вашем сценарии соседей по комнате, если один сосед по комнате выезжает, вы не хотите менять адрес для обоих соседей по комнате. – erg39
Если это действительно один-ко-многим, я бы переосмыслил его. Но я не верю, что эта конкретная ситуация оправдывает это.Предоставление этого одного-ко-многим дублирует данные в базе данных без необходимости. Повторяя ситуацию, вы не обновляете строку адресов для научного кида, оставаясь позади, вы просто измените основную часть компьютера, чтобы указать на новую запись адреса, уже существующую, если его девушка находится на кампусе или просто добавляет новый, если она пойдет в школу черлидинга по дороге :-) – paxdiablo
Технически не должно быть дубликатов строк в таблице вообще. Адрес - это объект, и все атрибуты для этого объекта должны быть в одной строке. Что происходит, когда у вас есть две строки для 7 Smith Street, и у них разные представления об адресе (например, арендная плата, или комнаты, оставшиеся в аренду)? DBAs путешествуют по миру, пытаясь устранить такие проблемы. Не заставляйте меня приходить туда :-) – paxdiablo