2010-02-01 1 views
4

и спасибо за чтение.Дизайн базы данных - NULL Foreign Keys

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

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

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

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

+11

Нам нужны фотографии щенков, чтобы лучше оценить ситуацию. –

+1

Слава богу, он не пишет приложение Pony Store. – APC

+1

Для справки см. Http://www.dailypuppy.com/ – RedFilter

ответ

10

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

+0

+1 потому что он отвечает вопрос, но я согласен с другими, что собака должна быть в состоянии владеть более чем одним человеком или, по крайней мере, принадлежащим магазину. – MrChrister

+3

Что касается магазина, кажется вероятным, что у щенка есть только один владелец. Возможно, Боб и Салли думают о Фидо как о «своем щенке», но с точки зрения магазина, они продали щенка одному человеку. Если возможно, что щенок будет возвращен и перепродан, и вам нужно вести учет этой истории, это будет другая история. – Jay

0

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

2

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

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

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

владелец щенка строк будет иметь две колонки: щенок-ID, владелец-идентификатор , Хотя вы говорите, что у щенка может быть только один владелец, факт состоит в том, что он, вероятно, будет «принадлежать» всем взрослым в семье. Если это шоу-собака, она, вероятно, будет принадлежать совладельцу и одному или нескольким другим.

5

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

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 пересечения, потому что собаки могут иметь более один владелец. Я знаю, что у меня есть!
+0

+1 Предполагая, что DogOwner.DogID и DogOwner.OwnerID являются «NOT NULL» i.e. model missing information, используя отсутствие строки в отношении. – onedaywhen

2

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

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

-3

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

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

+3

Это неоптимальное решение с точки зрения данных. Семантическое значение этого решения состоит в том, что у всех щенков есть владельцы, и вы должны знать, что ID # 1 == «Никто» не может исключить его с предложением WHERE. Предпочтительно, чтобы у нежилого щенка не было ценности владельца, потому что вывод о том, что у него нет владельца, является непосредственным и явным. –

+0

Наверняка это так. Это всего лишь обходной путь для случая, когда база данных не может хорошо индексировать нули. Например. в Oracle строка не включена в индекс, если все индексированные столбцы равны нулю. Если у вас небольшое количество нулей, вам нужно выполнить полную проверку, чтобы найти их, а для любого другого значения можно использовать гораздо более быстрый сканирование диапазона. Существует два типичных обходных пути: включение неиспользуемого ненулевого столбца в индекс или добавление фиктивного «псевдо-нулевого», как я предполагал. – 9000

-1
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