Чи вважатиметься поганою практикою мати на столі в SQL Server кілька нульових ФК


13

У моїй структурі бази даних в SQL Server у мене є 3 типи продуктів, для яких потрібна різна інформація про замовлення. Отже, я створив один Customersстіл і три різних таблиць замовлень: OrdersForProductAs, OrdersForProductBs, OrdersForProductCs. Усі таблиці замовлень мають один на багато відносин на Customersстолі.

У мене також є інша таблиця, яка є Paymentsі буде містити платіжні реквізити всередині. Але я маю сумніви в тому, як це структурувати.

Оскільки у мене є декілька типів товарів і клієнт може одночасно замовляти кілька продуктів, мені потрібно відновити ці три таблиці замовлення до Paymentsтаблиці.

Інше питання полягає в тому, що у замовника може бути замовлення лише на один вид товару. Отже, колонки FK на Paymentsстолі повинні бути nullable.

Моє запитання - чи будуть ці nullableколонки ФК головним болем для мене довгостроково чи ні? Взагалі кажучи, чи вважатиметься поганою практикою розміщення на столі стовпчикових стовпців FK?


2
Переконайтеся, що ви включили контрольне обмеження, щоб принаймні один із цих ФК не був нульовим.
Damien_The_Unbeliever

3
Один мінливий зовнішній ключ - це занадто багато.
nvogel

Відповіді:


13

Я б запитав, чому у вас взагалі є OrdersForProductXтаблиці
. Можливо, проблема ФК, про яку ви питали, може бути розроблена ...

Якщо ці таблиці мають однакову структуру, то вам просто потрібен ProductTypeстовпець на якійсь OrderProductтаблиці. Тоді Paymentпросто посилання на це з одним ФК

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

Це "шаблон супер-ключа / підтипу"

  • UQ1 - це "супер ключ", який використовується зовнішнім ключем у таблицях підтипу
  • У кожній таблиці підтипу є складені ПК та FK (OrderID, ProductType)
  • Кожна таблиця підтипу має обмеження для перевірки обмеження типів у цій таблиці

OrderProduct

  • OrderID, PK, UQ1
  • Тип продукту, 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ᵀᴹ

"Якщо ці таблиці мають однакову структуру" Вони не мають однакової структури.
буксир

5

Уникайте нульових "сторонніх ключів". Вони мають численні недоліки.

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

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

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

Деякі функції оптимізації запитів, що дозволяють перезаписувати запити та інші оптимізації, можуть бути недоступними, коли зовнішній ключ є нульовим.

З точки зору логіки, нульове обмеження "зовнішнього ключа" не має особливого логічного сенсу. Відповідно до стандарту SQL таке обмеження може не порушуватися, навіть якщо таблиця, на яку посилається, порожня. Це суперечить одному з найпоширеніших передбачуваних виправдань для використання нуля - тому, що він представляє "невідомий" випадок. Якщо немає дійсних значень X, то будь-який "невідомий" X, безумовно, не може бути дійсним значенням - і все ж SQL дозволить це.

Зменшувані сторонні ключі абсолютно непотрібні. Ви завжди можете або розкласти зовнішній ключ до нової таблиці або використовувати шаблон супертипу / підтипу, щоб нулі не потрібні. Зважаючи на простоту і точність, тому краще залишити нулі, ніж вводити їх.


2

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

(Як ви думаєте, чому це буде проблема?)


Спасибі! Ну, я не дуже впевнений у цьому, але у мене був такий проект, як пару років тому, і я пам’ятаю, що в мене щось боліло . Отже, мені незрозуміло, як ви бачите: з чого я задав питання.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.