Sarebbe considerato una cattiva pratica avere più FK annullabili su una tabella in SQL Server


13

Nella mia struttura di database in SQL Server, ho 3 tipi di prodotti che richiedono informazioni diverse sull'ordine. Così, ho creato un Customerstavolo e tre differenti tabelle ordini: OrdersForProductAs, OrdersForProductBs, OrdersForProductCs. La tabella di tutti gli ordini ha una o più relazioni sulla Customerstabella.

Ho anche un altro tavolo che è Paymentse conterrà i dettagli di pagamento all'interno. Ma ho dei dubbi qui su come strutturarlo.

Poiché ho più tipi di prodotto e un cliente può avere ordini per più prodotti contemporaneamente, ho bisogno di mettere in relazione queste tre tabelle degli ordini Payments.

L'altro problema è che un cliente può avere un ordine per un solo tipo di prodotto. Quindi, le colonne FK sulla Paymentstabella devono essere nullable.

La mia domanda è se quelle nullablecolonne FK sarebbero un mal di testa per me nel lungo periodo o no? In generale, sarebbe considerato una cattiva pratica avere colonne FK nullable su una tabella?


2
Assicurati di includere un vincolo di controllo in modo che almeno uno di questi FK non sia nullo.
Damien_The_Unbeliever,

3
Una chiave esterna nullable è troppa.
nvogel,

Risposte:


13

Mi chiedo perché hai delle OrdersForProductXtabelle.
È possibile che il problema FK che hai chiesto possa essere progettato ...

Se queste tabelle hanno la stessa struttura, allora hai semplicemente bisogno di una ProductTypecolonna su alcune OrderProducttabelle. Quindi Paymentcollega a quello con un solo FK

Se la tabella ha strutture diverse, suppongo che abbiano alcuni attributi comuni. Quindi, puoi avere una OrderProducttabella comune quindi una tabella figlio specifica per tipo di prodotto (vedi sotto) Ancora una volta, Paymentbasta collegare alla tabella comune con un FK

Questo è il "modello superkey / sottotipo"

  • UQ1 è la "super chiave" utilizzata una chiave esterna nelle tabelle dei sottotipi
  • Ogni tabella dei sottotipi ha un PK e un FK compositi attivi (OrderID, ProductType)
  • Ogni tabella dei sottotipi ha un vincolo CHECK per limitare i tipi in quella tabella

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: nota che non avrai NULLcolonne FK con questo approccio.
ypercubeᵀᴹ

"Se queste tabelle hanno la stessa struttura" Non hanno la stessa struttura.
Tugberk,

5

Evita "chiavi esterne" nullable. Hanno diversi svantaggi.

Il vincolo su una riga di riferimento non viene sempre applicato quando la chiave esterna contiene un valore null. Tuttavia, tale comportamento predefinito non è coerente tra diversi DBMS. Alcuni DBMS supportano le opzioni di configurazione per modificare il comportamento delle chiavi esterne nullable e altri no. Gli sviluppatori e gli utenti SQL potrebbero quindi non essere chiari sul significato di un vincolo di chiave esterna nullable dal punto di vista dell'integrità dei dati. Il porting del database tra prodotti DBMS o anche tra server diversi utilizzando lo stesso prodotto potrebbe dare risultati incoerenti.

Gli strumenti di progettazione del database, gli strumenti di integrazione e altri software non sempre li supportano correttamente e i risultati che producono potrebbero essere errati.

Le chiavi esterne vengono spesso utilizzate nei join e in altre logiche di query, aggravando i problemi per gli utenti che pensano che il vincolo sia attivo quando non lo è o che non conoscono la logica applicata dal proprio DBMS specifico.

Alcune funzioni di ottimizzazione delle query che consentono la riscrittura delle query e altre ottimizzazioni potrebbero non essere disponibili quando una chiave esterna è nullable.

In termini logici, un vincolo "chiave esterna" nullable non ha molto senso logico. Secondo lo standard SQL un tale vincolo non può essere violato anche se la tabella a cui si fa riferimento è vuota. Ciò contraddice una delle presunte giustificazioni più comuni per l'uso di un valore null - che rappresenta il caso "sconosciuto". Se non ci sono valori validi di X, qualsiasi X "sconosciuto" non può certamente essere un valore valido - eppure SQL lo consentirà.

Le chiavi esterne nullable sono completamente inutili. Puoi sempre scomporre la chiave esterna in una nuova tabella o utilizzare un modello supertipo / sottotipo in modo che non siano necessari valori null. Per motivi di semplicità e accuratezza, è quindi meglio escludere i null piuttosto che inserirli.


2

Non ho mai sentito parlare di cattive pratiche nell'uso di colonne FK nullable. Sono la soluzione ideale per una colonna che fa riferimento a un'altra tabella ma potrebbe non essere compilata (ovvero sono dati facoltativi).

(Perché pensi che sarebbe un problema?)


Grazie! Beh, non ne sono del tutto sicuro, ma ho avuto un progetto come quello un paio d'anni fa e ricordo che avevo mal di testa su qualcosa . Quindi, non sono chiaro come vedi: s ecco perché ho posto la domanda.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.