Будет ли плохой практикой иметь несколько обнуляемых FK на таблице в SQL Server


13

В моей структуре базы данных в SQL Server у меня есть 3 типа продуктов, которые требуют разной информации о заказе. Итак, я создал один Customersстол и три различных таблиц заказов: OrdersForProductAs, OrdersForProductBs, OrdersForProductCs. Стол всех заказов имеет отношение один ко многим на Customersстоле.

У меня также есть другая таблица, которая содержит Paymentsи будет содержать детали платежа внутри. Но у меня есть сомнения в том, как это структурировать.

Поскольку у меня несколько типов продуктов, и у клиента могут быть заказы на несколько продуктов одновременно, мне нужно связать эти три таблицы заказов с Paymentsтаблицей.

Другая проблема заключается в том, что у клиента может быть заказ только на один тип продукта. Итак, столбцы FK на Paymentsтаблице должны быть nullable.

Мой вопрос: будут ли эти nullableстолбцы FK головной болью для меня в долгосрочной перспективе или нет? Вообще говоря, будет ли плохой практикой иметь в таблице обнуляемые столбцы FK?


2
Убедитесь, что вы включили проверочное ограничение, чтобы хотя бы один из этих FK не был нулевым.
Damien_The_Unbeliever

3
Один обнуляемый внешний ключ - это слишком много.
nvogel

Ответы:


13

Я бы спросил, почему у вас вообще есть OrdersForProductXтаблицы
? Возможно, проблема FK, о которой вы спрашивали, может быть разработана ...

Если эти таблицы имеют одинаковую структуру, то вам просто нужен ProductTypeстолбец в некоторой OrderProductтаблице. Тогда Paymentпросто ссылки на это с одним FK

Если таблица имеет разные структуры, я предполагаю, что они имеют некоторые общие атрибуты. Таким образом, вы можете иметь общую OrderProductтаблицу, а затем конкретную дочернюю таблицу для каждого типа продукта (см. Ниже). Опять же, Paymentпросто ссылки на общую таблицу с одним FK

Это «шаблон суперключа / подтипа»

  • UQ1 - это «супер ключ», который использует внешний ключ в таблицах подтипов
  • Каждая таблица подтипов имеет составной PK и FK на (OrderID, ProductType)
  • Каждая таблица подтипов имеет ограничение CHECK для ограничения типов в этой таблице.

OrderProduct

  • OrderID, PK, UQ1
  • ProductType, UQ1
  • CommonThing1
  • ...

OrderProductA

  • OrderID, PK, FK
  • ProductType, PK, FK, CHECK ProductType = A
  • ProductAThing1
  • ...

OrderProductB

  • OrderID, PK, FK
  • ProductType, PK, FK, CHECK ProductType = B
  • ProductBThing1
  • ...

4
@tugberk: обратите внимание, что NULLпри таком подходе у вас не будет столбцов FK.
ypercubeᵀᴹ

«Если эти таблицы имеют одинаковую структуру», они не имеют одинаковую структуру.
Tugberk

5

Избегайте обнуляемых «внешних ключей». У них есть несколько недостатков.

Ограничение на ссылочную строку не всегда применяется, когда внешний ключ содержит ноль. Однако такое поведение по умолчанию не согласовано между различными СУБД. Некоторые СУБД поддерживают параметры конфигурации для изменения поведения внешних ключей, допускающих нулевое значение, а некоторые - нет. Поэтому разработчики и пользователи SQL могут не знать, что на самом деле означает обнуляемое ограничение внешнего ключа с точки зрения целостности данных. Портирование базы данных между продуктами СУБД или даже между различными серверами, использующими один и тот же продукт, может дать противоречивые результаты.

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

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

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

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

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


2

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

(Как вы думаете, почему это будет проблемой?)


Благодарность! Ну, я не совсем уверен в этом, но у меня был такой проект пару лет назад, и я помню, что у меня что- то болело . Итак, мне не ясно, как вы видите: почему я задал вопрос?
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.