I database relazionali non sono creati per gestire perfettamente questa situazione. Devi decidere cosa è più importante per te e poi fare i tuoi compromessi. Hai diversi obiettivi:
- Mantieni la terza forma normale
- Mantenere l'integrità referenziale
- Mantenere il vincolo che ogni account appartiene a una società o una persona fisica.
- Preservare la capacità di recuperare i dati in modo semplice e diretto
Il problema è che alcuni di questi obiettivi competono tra loro.
Soluzione di
sottotipo Puoi scegliere una soluzione di sottotipo in cui crei un super-tipo che incorpori sia le società che le persone. Questo super-tipo avrebbe probabilmente una chiave composta dalla chiave naturale del sottotipo più un attributo di partizionamento (ad es customer_type
.). Questo va bene per quanto riguarda la normalizzazione e ti permette di imporre l'integrità referenziale così come il vincolo che le società e le persone si escludono a vicenda. Il problema è che ciò rende più difficile il recupero dei dati, perché devi sempre diramarti in base a customer_type
quando unisci l'account al titolare dell'account. Questo probabilmente significa usare UNION
e avere un sacco di SQL ripetitivo nella tua query.
Soluzione con
due chiavi esterne È possibile scegliere una soluzione in cui tenere due chiavi esterne nella tabella del proprio account, una alla società e una alla persona. Questa soluzione consente inoltre di mantenere l'integrità referenziale, la normalizzazione e l'esclusività reciproca. Ha anche lo stesso inconveniente di recupero dei dati della soluzione di sotto-digitazione. In effetti, questa soluzione è proprio come la soluzione di sotto-digitazione, tranne per il fatto che si arriva al problema di ramificare la logica di giunzione "prima".
Tuttavia, molti modellatori di dati considererebbero questa soluzione inferiore alla soluzione di sotto-tipizzazione a causa del modo in cui viene applicato il vincolo di mutua esclusività. Nella soluzione di digitazione secondaria si utilizzano i tasti per applicare l'esclusività reciproca. Nella soluzione con due chiavi esterne si utilizza un CHECK
vincolo. Conosco alcune persone che hanno un pregiudizio ingiustificato contro i vincoli di controllo. Queste persone preferirebbero la soluzione che mantiene i vincoli nelle chiavi.
Soluzione di attributo di partizionamento "denormalizzato"
Esiste un'altra opzione in cui si mantiene una singola colonna di chiave esterna sulla tabella degli account chequing e si utilizza un'altra colonna per indicare come interpretare la colonna di chiave esterna (RoKa'sOwnerTypeID
colonna). Questo essenzialmente elimina la tabella dei super-tipi nella soluzione di sotto-digitazione denormalizzando l'attributo di partizionamento nella tabella figlio. (Si noti che questa non è strettamente "denormalizzazione" secondo la definizione formale, perché l'attributo di partizionamento fa parte di una chiave primaria.) Questa soluzione sembra abbastanza semplice poiché evita di avere una tabella aggiuntiva per fare più o meno la stessa cosa e riduce il numero di colonne di chiave esterna a una. Il problema con questa soluzione è che non evita la ramificazione della logica di recupero e, inoltre, non consente di mantenere l' integrità referenziale dichiarativa . I database SQL non hanno la capacità di gestire una singola colonna di chiave esterna per una delle tabelle padre multiple.
Soluzione di dominio chiave primaria condivisa
Un modo in cui le persone a volte affrontano questo problema è utilizzare un singolo pool di ID in modo che non ci sia confusione per un determinato ID se appartiene a un sottotipo o a un altro. Questo probabilmente funzionerebbe in modo abbastanza naturale in uno scenario bancario, dal momento che non emetterete lo stesso numero di conto bancario sia a una società che a una persona fisica. Ciò ha il vantaggio di evitare la necessità di un attributo di partizionamento. Puoi farlo con o senza una tabella di super-tipo. L'uso di una tabella dei super-tipi consente di utilizzare i vincoli dichiarativi per applicare l'univocità. Altrimenti ciò dovrebbe essere applicato proceduralmente. Questa soluzione è normalizzata ma non consente di mantenere l'integrità referenziale dichiarativa se non si mantiene la tabella dei super-tipi. Non fa ancora nulla per evitare complesse logiche di recupero.
Potete quindi vedere che non è davvero possibile avere un design pulito che segua tutte le regole, mantenendo allo stesso tempo semplice il recupero dei dati. Devi decidere dove saranno i tuoi compromessi.
OwnerTypeID
nelChecquingAccount
tavolo, con1=Corporation
e2=NaturalPerson
? In questo modo ne hai bisogno solo unoOwnerID
nellaChecquingAccount
tabella, che puoi indicizzare insieme aOwnerTypeID
.