Wäre es eine schlechte Praxis, mehrere nullfähige FKs in einer Tabelle in SQL Server zu haben?

13

In meiner Datenbankstruktur in SQL Server gibt es drei Arten von Produkten, für die unterschiedliche Informationen zur Bestellung erforderlich sind. Also, habe ich einen CustomersTisch und drei verschiedene Aufträge Tabellen: OrdersForProductAs, OrdersForProductBs, OrdersForProductCs. Die Tabelle mit allen Bestellungen hat eine bis viele Beziehungen auf dem CustomersTisch.

Ich habe auch eine andere Tabelle, die Paymentsdie Zahlungsdetails enthält und enthalten wird. Aber ich habe hier Zweifel, wie ich es strukturieren soll.

Da ich mehrere Produkttypen habe und ein Kunde möglicherweise gleichzeitig mehrere Produkte bestellt, muss ich diese drei Auftragstabellen mit Tabellen verknüpfen Payments.

Das andere Problem ist, dass ein Kunde möglicherweise nur eine Produktart bestellt. Also müssen die FK-Spalten auf dem PaymentsTisch sein nullable.

Meine Frage ist, ob nullablemir diese FK-Säulen auf lange Sicht Kopfzerbrechen bereiten würden oder nicht. Wäre es im Allgemeinen eine schlechte Praxis, nullfähige FK-Spalten in einer Tabelle zu haben?

Tugberk
quelle
2
Stellen Sie sicher, dass Sie eine Prüfbedingung einfügen , damit mindestens eine dieser FKs nicht null ist.
Damien_The_Unbeliever
3
Ein nullbarer Fremdschlüssel ist einer zu viel.
nvogel

Antworten:

13

Ich würde fragen, warum Sie überhaupt OrdersForProductXTische haben.
Möglicherweise kann das FK-Problem, das Sie gefragt haben, herausgearbeitet werden ...

Wenn diese Tabellen dieselbe Struktur haben, benötigen Sie lediglich eine ProductTypeSpalte in einer OrderProductTabelle. Dann Paymenteinfach mit einem FK darauf verlinken

Wenn die Tabelle unterschiedliche Strukturen hat, gehe ich davon aus, dass sie einige gemeinsame Attribute haben. Sie können also eine gemeinsame OrderProductTabelle und dann eine bestimmte Paymentuntergeordnete Tabelle pro Produkttyp haben (siehe unten). Auch hier müssen Sie nur mit einer FK auf die gemeinsame Tabelle verweisen

Dies ist das "Superkey / Subtyp-Muster"

  • UQ1 ist der "Superschlüssel", der für die Subtyp-Tabellen als Fremdschlüssel verwendet wird
  • Jede Subtyp-Tabelle hat ein zusammengesetztes PK und ein FK (OrderID, ProductType)
  • Jede Subtyp-Tabelle hat eine CHECK-Einschränkung, um die Typen in dieser Tabelle einzuschränken

OrderProduct

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

OrderProductA

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

OrderProductB

  • OrderID, PK, FK
  • Produkttyp, PK, FK, CHECK Produkttyp = B
  • ProductBThing1
  • ...
gbn
quelle
4
@tugberk: Beachten Sie, dass Sie NULLbei diesem Ansatz keine FK-Spalten haben .
ypercubeᵀᴹ
"Wenn diese Tabellen die gleiche Struktur haben" Sie haben nicht die gleiche Struktur.
Tugberk
5

Vermeiden Sie nullfähige "Fremdschlüssel". Sie haben mehrere Nachteile.

Die Einschränkung für eine referenzierende Zeile wird nicht immer erzwungen, wenn der Fremdschlüssel eine Null enthält. Dieses Standardverhalten ist jedoch zwischen verschiedenen DBMS nicht konsistent. Einige DBMS unterstützen Konfigurationsoptionen zum Ändern des Verhaltens nullfähiger Fremdschlüssel, andere nicht. SQL-Entwickler und -Nutzer sind sich daher möglicherweise nicht sicher, was eine nullbare Fremdschlüsseleinschränkung aus Sicht der Datenintegrität tatsächlich bedeutet. Das Portieren der Datenbank zwischen DBMS-Produkten oder sogar zwischen verschiedenen Servern, die dasselbe Produkt verwenden, kann zu inkonsistenten Ergebnissen führen.

Datenbank-Design-Tools, Integrationstools und andere Software unterstützen sie nicht immer richtig und die Ergebnisse, die sie produzieren, können falsch sein.

Fremdschlüssel werden häufig in Verknüpfungen und anderen Abfragelogiken verwendet, was die Probleme für Benutzer verschärft, die glauben, dass die Einschränkung wirksam ist, wenn sie nicht vorhanden ist oder die von Ihrem bestimmten DBMS angewendete Logik nicht kennt.

Einige Funktionen zur Abfrageoptimierung, die das Umschreiben von Abfragen und andere Optimierungen ermöglichen, sind möglicherweise nicht verfügbar, wenn ein Fremdschlüssel auf Null gesetzt werden kann.

In logischen Begriffen macht eine nullbare "Fremdschlüssel" -Beschränkung nicht viel logischen Sinn. Gemäß dem SQL-Standard darf eine solche Einschränkung nicht verletzt werden, auch wenn die Tabelle, auf die verwiesen wird, leer ist. Dies widerspricht einer der häufigsten angeblichen Rechtfertigungen für die Verwendung einer Null - dass es sich um den "unbekannten" Fall handelt. Wenn es keine gültigen Werte für X gibt, kann jedes "unbekannte" X mit Sicherheit kein gültiger Wert sein - und SQL wird dies dennoch zulassen.

Nullable Fremdschlüssel sind völlig unnötig. Sie können den Fremdschlüssel immer entweder in eine neue Tabelle zerlegen oder ein Supertyp / Subtyp-Muster verwenden, sodass keine Nullen erforderlich sind. Aus Gründen der Einfachheit und Genauigkeit ist es daher besser, Nullen wegzulassen, als sie einzugeben.

nvogel
quelle
2

Ich habe noch nie gehört, dass die Verwendung nullwertfähiger FK-Spalten als schlechte Praxis angesehen wird. Sie passen ideal zu einer Spalte, die auf eine andere Tabelle verweist, jedoch möglicherweise nicht ausgefüllt ist (dh es handelt sich um optionale Daten).

(Warum denkst du, wäre es ein Problem?)

StilesCrisis
quelle
Vielen Dank! Nun, da bin ich mir nicht ganz sicher, aber ich hatte vor ein paar Jahren ein Projekt wie dieses und ich erinnere mich, dass ich Kopfschmerzen bei etwas hatte . Wie Sie sehen, ist mir nicht klar, warum ich die Frage gestellt habe.