2010-05-18 2 views
1

Вот сценарий: у вас есть таблица «Персоны» с отношением «один ко многим» с таблицей «Адреса», где одна из строк «Адрес» - основной адрес.Каков наилучший дизайн схемы для дочерней коллекции с «основным» объектом

Является ли это лучше в нормализованной схеме на

  • Используйте Persons.PrimaryAddressID для доступа к "основной" Адрес для лица

или

  • использовать адреса. IsPrimary для ссылки на «первичный» адрес для лица через адреса. PIDID

или

  • Другое

и почему?

ответ

1

Это зависит от того, является ли отношение «человек к адресу» равным нулю или плюс к одному.

Если у человека требуется первичный адрес, я бы поместил его в таблицу 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 несколько. Прагматизм часто побеждает догматизм в реальном мире :-)

+0

Не могли бы вы использовать этот дизайн, если отношение Person-> Addresses было привязано к одному-ко-многим, в отличие от мужчины-ко-многим, которое это разрешает? В этом случае иногда могут возникать дубликаты адресов, но, например, в вашем сценарии соседей по комнате, если один сосед по комнате выезжает, вы не хотите менять адрес для обоих соседей по комнате. – erg39

+0

Если это действительно один-ко-многим, я бы переосмыслил его. Но я не верю, что эта конкретная ситуация оправдывает это.Предоставление этого одного-ко-многим дублирует данные в базе данных без необходимости. Повторяя ситуацию, вы не обновляете строку адресов для научного кида, оставаясь позади, вы просто измените основную часть компьютера, чтобы указать на новую запись адреса, уже существующую, если его девушка находится на кампусе или просто добавляет новый, если она пойдет в школу черлидинга по дороге :-) – paxdiablo

+0

Технически не должно быть дубликатов строк в таблице вообще. Адрес - это объект, и все атрибуты для этого объекта должны быть в одной строке. Что происходит, когда у вас есть две строки для 7 Smith Street, и у них разные представления об адресе (например, арендная плата, или комнаты, оставшиеся в аренду)? DBAs путешествуют по миру, пытаясь устранить такие проблемы. Не заставляйте меня приходить туда :-) – paxdiablo

0

Я хотел бы воспользоваться «Персонализацией» для доступа к «Первичному» адресу для лица ». Первичный адрес имеет значение только тогда, когда Person связан с Адресами. Поэтому он должен принадлежать Личности. Подумайте о следующих сценариях, где сбой второго подхода.

a) Адрес используется с другим лицом без ссылки на человека, где Addresses.IsPrimary не имеет смысла.

b) Тот же адрес используется двумя лицами, где первый использует как первичный, а второй нет.

+0

Хороший вопрос о том, как «первичный» имеет смысл, когда существует связь. – erg39

0

Если вы хотите ограничение быть, что один человек имеет не более одного первичный адрес, Persons.PrimaryAddressID явно проще - действительно, он применяется самой схемой. Также легко обеспечить ровно один первичный адрес на одного человека (просто сделайте этот столбец не нулевым), и если вам нужно, даже скажите, что ни один из двух человек не может использовать первичный адрес (просто сделайте этот столбец уникальным).

Конечно, именно потому, что этот подход превосходит при соблюдении таких простых ограничений, это плохо, если вы не нуждаетесь в этих ограничениях, например, если вы хотите, чтобы у человека было более одного «первичный» адрес, подход, о котором идет речь, не будет работать.

Кстати, я бы не рассмотрим/много-адреса отношения один-Person быть особенно хорошо если вы хотите обеспечить тот факт, что нет двух людей, не могут делиться и тот же адрес: вообще, в нормализующего настроение, Я бы предпочел иметь таблицу людей, один из адресов и один для отношений (что в большинстве контекстов, естественно, будет много-ко-многим, так как многие люди могут и в реальной жизни имеют одинаковый адрес).

Если вы решите пойти по этому маршруту, то, особенно если вам нужна высокая гибкость (несколько первичных адресов & c), имея таблицу отношений, несущую логику «primality», будет привлекательным выбором (она все еще делает это не слишком трудно обеспечить соблюдение некоторых из вышеупомянутых ограничений, хотя другие ограничения, такие как «адрес принадлежит хотя бы одному человеку» или наоборот, могут быть сложными, чтобы выразить просто).

Занятие для удержания: выражайте то, что ограничивает вашу схему просто, и правильная схема для этой цели часто возникает достаточно четко. Если ограничения интереса являются загадкой, так будет ответ на вопрос «что такое правильная схема» ;-).

Смежные вопросы