значение по умолчанию против нуля для внешнего ключа - PullRequest
3 голосов
/ 15 апреля 2011

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

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

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

Теперь у меня есть два / три варианта:

A: Я допускаю, чтобы столбец NationalityID (и все другие подобные столбцы внешнего ключа в базе данных) был нулевым и просто придерживался общего подхода проверки всегда и везде на нулевое значение (применение правил в приложении)

или

B: Я назначаю значение по умолчанию для каждого внешнего ключа, скажем, «-1», и добавляю в каждый столбец таблицы отношений дополнительный столбец с «-1» в качестве ключа и все другие данные как «Нет данных» (для этого Например, в таблице Country я поставил столбец с CountryID "-1", а для CountryName я установил "Нет данных"). Поэтому каждый раз, когда я захочу узнать национальность пользователя, я всегда получаю результат без дополнительных правил кода (мне не нужно проверять, является ли он нулевым или нет).

или

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

Так Б хороший подход или нет? Что мне здесь не хватает? Я теряю больше, что я получаю с этим подходом? Какие проблемы могут возникнуть (кроме того, чтобы всегда иметь дополнительный столбец в реляционных таблицах со значением идентификатора «-1», в котором говорится, что «нет данных»)?

Какой у вас хороший / плохой опыт использования значений по умолчанию для внешнего ключа?

спасибо

Ответы [ 5 ]

8 голосов
/ 15 апреля 2011

Если вы нормализуете это не будет проблемой.

Вместо того, чтобы указывать национальность в таблице USER, создайте таблицу User_Nationality, которая связывает пользователей с Country_IDв другой таблице.

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

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

Используйте таблицы поиска, и вы можете обойтиэто полностью.

Это также позволит вам передумать и выбрать один из вариантов в будущем.

Если вы используете представления, вы можете рассматривать пропущенные данные какNULL или значение по умолчанию без необходимости изменения базовых данных.

3 голосов
/ 15 апреля 2011

Лично я чувствую, что даже если у вас есть запись без записи в вашей базе данных с ключом -1, вы все равно будете выполнять проверку, чтобы увидеть, хотите ли вы отображать «Нет данных» или нет для каждогоиндивидуальное поле.

Я бы придерживался NULL.NULL означает отсутствие данных, как здесь.

1 голос
/ 15 апреля 2011

Я предлагаю вариант D. Если не все пользователи имеют определенную национальность, то эта информация не входит в таблицу пользователей. Создайте таблицу с именем UserNationality на основе идентификатора пользователя.

1 голос
/ 15 апреля 2011

Б - это ужасный подход.Проще запомнить обработчик нулей, чем выяснить, какое магическое число вы использовали, и тогда вам все равно придется обрабатывать их.Используйте номер 1. Но мне больше всего нравится идея JNK.

1 голос
/ 15 апреля 2011

Мне нравится ваше решение B. Возможно, будет возможно отобразить значения в другие сущности, поэтому у вас есть Country и NullCountry, который расширяет Country и отображается в строку с id = -1 и имеет специальный код в своих методах, чтобы упростить обработку особых случаев.

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

РЕДАКТИРОВАТЬ: нет, не должно быть никаких проблем с внешними объединениями, потому что не было бы необходимости делать внешние объединения.

...