Проектирование базы данных - внешние ключи NULL - PullRequest
4 голосов
/ 01 февраля 2010

и спасибо за чтение.

Я создаю базу данных для магазина щенков. У меня есть стол для щенков и стол для хозяев. У щенка может быть один владелец, владельцы могут владеть более чем одним щенком, но не все щенки принадлежат. Какой хороший способ справиться с этой ситуацией?

  • Должен ли я использовать FK в таблице щенков, который равен NULL, если у щенка нет владельца?
  • Создаю ли я ассоциативную таблицу, которая представляет собой сопоставление владельцев со щенками «один ко многим», и на щенках есть флажок, который помечается, если щенок не принадлежит?
  • Я создаю две таблицы? Одна таблица может быть для щенков, которые находятся в собственности, и она имеет ненулевой FK для таблицы владельца, а другая таблица, которая содержит щенков, которые не принадлежат?

Спасибо за помощь.

Этот вопрос действительно направлен на то, как пометить строку как глобальную и разрешенную для просмотра любому пользователю?

Ответы [ 7 ]

11 голосов
/ 01 февраля 2010

Решение 1) является правильным. У щенка может не быть ни владельца, ни одного владельца, поэтому столбец заполняется существующим владельцем или имеет значение NULL.

5 голосов
/ 01 февраля 2010

У меня были бы следующие таблицы:

Dog
Owner
DogOwner (contains non-nullable DogID and OwnerID FKs that together make up the PK)

Тогда вы бы сделали:

select *
from Dog d
left outer join DogOwner do on d.DogID = do.DogID
left outer join Owner o on do.OwnerID = o.OwnerID

Этот запрос возвращает всех собак, даже тех, у которых нет владельца.

Это имеет несколько улучшений по сравнению с вашим дизайном:

  • Называет таблицу Dog, потому что собаки не остаются щенками очень долго (нюхает)
  • Используется таблица пересечений DogOwner, потому что у Собак может быть более одного владельца. Я знаю, что мой делает!
3 голосов
/ 01 февраля 2010

Если каждый щенок действительно может принадлежать только одному и только одному человеку, да, конечно, оставьте fk пустым / NULL, если он еще не принадлежит.

В противном случае я предлагаю 3 таблицы

  • информация о щенке
  • информация о владельце
  • щенок-владелец

строки владельца щенка будут иметь два столбца: идентификатор щенка, идентификатор владельца. Даже если вы говорите, что у щенка может быть только один владелец, фактом является то, что он, вероятно, будет "принадлежать" всем взрослым в домашнем хозяйстве. Если это выставочная собака, то, скорее всего, она будет совладельцем заводчика и одного или нескольких других.

2 голосов
/ 01 февраля 2010

Это интересная проблема моделирования, потому что можно утверждать, что магазин щенков владеет всеми щенками, которые не принадлежат никому другому. В конце концов, если Li'l Cujo неистовствует и кусает лодыжки нескольких покупателей, владелец магазина щенков будет нести ответственность за все эти столбнячные уколы. Когда Патти Пейдж купила эту собачку для своей возлюбленной, сделка была сменой владельца, а не ее созданием.

Логика этого аргумента заключается в том, что OwnerId является столбцом NOT NULL.

0 голосов
/ 02 февраля 2010
Create table owner (ownerid int PRIMARY KEY, ownername varchar(50) not null)

Create table dog(ownerid int, dogid int, dogname varchar(50), CONSTRAINT pk_col PRIMARY KEY (ownerid, dogid), constraint fk_col foreign key (ownerid) references owner(ownerid) );

Это лучшее решение, которое вы можете иметь. Что означает дизайн таблицы, так это то, что у вас есть список владельцев в таблице владельцев, а в таблице собака есть только те записи, в которых владелец существует в таблице владельцев, которая является родительской таблицей, и у него есть собака. Это только те щенки, у которых есть хозяин, имеют доступ к столу собаки.

Запрос для поддержки ваших требований.

SELECT owner.ownerid, dog.dogid, dog.dogname FROM owner, dog
WHERE owner.ownerid = dog.ownerid
0 голосов
/ 01 февраля 2010

Вы можете создать специального владельца "Никто" и сделать так, чтобы все неопубликованные щенки ссылались на него, вместо того, чтобы иметь нулевого владельца. Это может иметь смысл, если ваша база данных не может индексировать нулевые FK, и у вас возникают проблемы с производительностью при поиске незнакомых щенков.

Это немного усложняет дизайн; если сомневаетесь, попробуйте сначала подход нулевого владельца.

0 голосов
/ 01 февраля 2010

С вашими столами (Щенок и Владелец) должно быть все в порядке. В вашей таблице Puppy, у вас будет столбец с именем что-то вроде OwnerID, которое является FK для таблицы Owner. Это нормально, чтобы позволить этому быть NULL. Когда он нулевой, никому не принадлежит щенок.

...