Неверный внешний ключ плохой практики?

Скажем, у вас есть таблица заказов с внешним ключом для идентификатора клиента. Теперь предположим, что вы хотите добавить заказ без идентификатора клиента (возможно, это будет другой вопрос), вам нужно сделать внешний ключ NULL... Является ли эта плохая практика или вы предпочитаете работать со ссылочной таблицей между Заказы и клиенты? Хотя отношение равно от 1 до n, таблица ссылок сделает n равным n. С другой стороны, со ссылкой, у меня больше нет этих NULLS...

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

(В моем случае это не Заказ и Клиент).

EDIT: а как насчет неназначенного Клиента для ссылки?

Ответ 1

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

На боковой ноте; использование таблицы ссылок необязательно делает его n равным n, если в таблице ссылок используется внешний ключ, указывающий на таблицу заказов в качестве первичного ключа в этой таблице ссылок, отношение все равно 1..n. В каждой таблице ссылок может быть только одна запись.

Ответ 2

Нет Нет ничего плохого в Nullable FK. Это обычное явление, когда объект, к которому указывает FK, находится в (от нуля или один) до (1 или много) отношений с таблицей, на которую ссылается первичный ключ.

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

Ответ 3

Nullable columns может быть в 1NF через 5NF, но не в 6NF в соответствии с тем, что я читал.

Только если вы знаете лучше, чем Крис Даун, "какая первая нормальная форма действительно означает". Если x и y равны нулю, и действительно, в некоторой строке x и y оба null, то WHERE x=y не дает true. Это неопровержимо доказывает, что null не является значением (потому что любое реальное значение всегда равно самому себе). И поскольку RM предписывает, что "в каждой ячейке таблицы должно быть значение", любая вещь, которая может содержать нули, не является реляционной вещью, и поэтому вопрос о 1NF даже не возникает.

Я слышал, что он утверждал, что Nullable столбцы вообще нарушают первую степень нормализации.

См. выше для обоснованной причины, лежащей в основе этого аргумента.

Но на практике это очень практично.

Только если вы невосприимчивы к головным болям, которые обычно возникают у всего остального мира. Одна из таких головных болей (и это лишь незначительная, по сравнению с другими феноменами null) заключается в том, что WHERE x=y в SQL фактически означает WHERE x is not null and y is not null and x=y, но большинство программистов просто не знают об этом факте и просто читают Это. Иногда без вреда, иногда нет.

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

Использование NULL было бы хорошим способом для очистки неполных заказов:

SELECT * FROM `orders`
WHERE `started_time` < (UNIX_TIMESTAMP() + 900) AND `customer_id` IS NULL

Вышеуказанные порядки будут старше 15 минут без соответствующего идентификатора клиента.

Ответ 7

Nullable FKs для необязательных отношений "много-к-одному" полностью прекрасны.

Ответ 8

Если вы только временно добавляете заказ без идентификатора клиента до тех пор, пока клиент не будет определен, было бы проще добавить клиента и заказать в одной транзакции, тем самым устраняя необходимость в записи NULL с внешним ключом и избегая любых ограничения или триггеры, которые вы настроили нарушить?

Обычно эта ситуация возникает в веб-приложениях, где заказ детализирован до того, как клиент определит, кто он/она. И в этих ситуациях заказ сохраняется в состоянии сервера или в файле cookie, пока не будет предоставлено все необходимое состояние для полного заказа, после чего заказ сохраняется в базе данных.

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

Ответ 9

Вы всегда можете добавить искусственную строку в таблицу Customer, что-то вроде Id = -1 и CustomerName = 'Unknown', а затем в случаях, когда вы обычно устанавливаете CustomerId в порядке NULL, установите его равным -1.

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

Ответ 10

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

Ответ 11

Да что-то не так. Его не является внешним ключом, если его значение недействительно. Его дизайн базы данных по коду. Возможно, вы сделаете нулевую ссылку на неназначенный. или "Неназначенные", если вы используете символ col. Сохраняйте целостность ваших данных на 100%.