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

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

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

Тем не менее, другая возможность - поместить таблицу между двумя таблицами - например, "собачники" - и поместить туда первичный ключ обеих таблиц, если у собаки есть владелец.

Теперь мой вопрос (как вы могли догадаться), какой из этих двух методов лучший и почему?

6 ответов

Единственное решение, которое соответствует принципам реляционной модели, - это дополнительная таблица.

Более того, трудно представить, как вы найдете какое-либо медленное оборудование, которое будет заметно по производительности при запуске запросов. В конце концов, это не критически важное приложение с десятками тысяч транзакций в секунду, не так ли?

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

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

Обнуляемый внешний ключ является типичным решением.

Самый простой из них - это просто иметь другую таблицу владельцев и собак с внешними ключами для владельцев и таблицы собак с столбцом собаки UNIQUE NOT NULL. Тогда, если вы хотите иметь только владельцев или собак, которым вы владеете, вам не нужно привлекать IS NOT NULL к вашим запросам, и СУБД не нужно получать к ним доступ среди всех владельцев и собак. Значения NULL могут упростить определенные ситуации, подобные этой, но они также усложняются по сравнению с наличием отдельной таблицы и простым объединением, когда вам нужны эти данные.

Однако, если у собаки может появиться несколько владельцев, вам может понадобиться дополнительная таблица в любом случае: многие отношения без столбца UNIQUE NOT NULL и пара столбцов владелец-собака UNIQUE NOT NULL. Вы всегда можете начать с одного UNIQUE NOT NULL и перейти к другому, если что-то изменится.

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

Является ли "владелец" (человек) действительно признаком собаки? Мне кажется, что вы хотите смоделировать отношения "владение" между человеком и собакой.

Другое полезное правило - избегать нулевых значений SQL! Трехзначная логика вводит в заблуждение большинство пользователей и программистов, нулевое поведение несовместимо во всем стандарте SQL и (как указывает sqlvogel) поставщики СУБД SQL реализуют разные вещи. Лучший способ моделирования отсутствующих данных - это пропуск кортежа в relvar (иначе ничего не вставляйте в свою таблицу!). Например, Fido входит в Dog но опущено из DogOwnership затем в соответствии с предположением о закрытом мире Fido к сожалению, не имеет владельца.

Все это указывает на наличие двух таблиц и отсутствие обнуляемых столбцов.

Я бы не стал делать дополнительную таблицу. Если по какой-либо причине пустые значения не допускаются (это хороший вопрос, почему) - я бы, и я знаю, что некоторые решения делают то же самое, вместо значения null ставят какое-то значение, которое не может быть реальным ключом. например, NOT_SET или около того.

Надеюсь, поможет

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

Добавление еще одной таблицы для соединения таблицы владельцев с таблицей собак создаст взаимосвязь "многие ко многим", если только в одном из ее столбцов не создано уникальное ограничение (в вашем случае - собаки).

Поскольку вы описываете отношение "один ко многим", я бы выбрал первый вариант, имея в виду наличие внешнего ключа, который может иметь значение NULL, поскольку я считаю его более читабельным.

Другие вопросы по тегам