Non penso che tu abbia un problema con le relazioni. Penso invece che il problema sia che usando chiavi surrogate (cioè ID) per ogni tabella il database risultante non è in grado di impedire l'inserimento dei lavoratori il cui dipartimento appartiene a una società mentre la classificazione è di un'altra e viceversa. Un buon modo per capire questo è visualizzare lo schema usando uno strumento di diagramma ER. Userò l'Oracle Data Modeler strumento che è un download gratuito.
Diagramma ER
Allo stato attuale, potresti avere 2 aziende - diciamo IBM
e Microsoft
. IBM
può avere un Software Development
dipartimento e Microsoft può avere un Desktop Software
dipartimento. IBM può avere una Software Engineer
classificazione e Microsoft può avere una Software Developer
classificazione. Ora, perché hai una chiave surrogata per Department
e Classification
, il fatto che Software Development
sia un IBM
dipartimento ed Desktop Software
è un Microsoft
dipartimento è perso per le future relazioni con i bambini. Questo è anche il caso di Classification
. Pertanto è facile assegnare accidentalmente Harlan Mills
, chi è un IBM
dipendente del Software Development
dipartimento, una classificazione di Software Developer
cui è unMicrosoft
classificazione! Allo stesso modo, al lavoratore potrebbe essere data la giusta classificazione e il reparto sbagliato! Ecco un diagramma che mostra il primo esempio:
I 1 ID rappresentano IBM
e i 2 ID rappresentano Microsoft
. Ho evidenziato in rosso lo scenario in cui Harlan Mills
e Bill Gates
sono assegnati ai dipartimenti sbagliate, che viene visualizzato dal Id 10 servizio associato al 200 classificazione di Id e viceversa.
Opzioni da risolvere
Quindi quali sono le opzioni per impedire che accada? Ci sono due opzioni immediate. Il primo è rendersi conto che utilizzando una chiave surrogata per ogni tabella questo problema esiste e introdurre una programmazione aggiuntiva per verificare che non si verifichi. Ciò potrebbe essere fatto nell'applicazione, ma se inserimenti e aggiornamenti possono verificarsi al di fuori dell'applicazione, possono comunque verificarsi associazioni errate. Un approccio migliore sarebbe quello di creare un trigger che si attiva all'inserimento e all'aggiornamento di un dipendente per assicurarsi che il reparto assegnato sia della stessa azienda della classificazione assegnata e, in caso contrario, l'inserimento o l'aggiornamento.
La seconda opzione è di non usare chiavi surrogate per ogni tabella. Utilizzare invece le chiavi surrogate solo per la Company
tabella, che è fondamentale e non ha genitori, quindi creare relazioni di identificazione con le tabelle Department
e Classification
figlio. Le tabelle Department
e Classification
ora hanno un PK di Company Id
più un numero di sequenza o un nome per distinguerli. Quindi, anche le relazioni da Department
e Classification
per Worker
diventare identifying
e quindi il PK di Worker
diventa il Company Id
, più il Department Number
(sto usando un numero progressivo in questo esempio), più il Classification Number
. Il risultato è che c'è solo one
Company Id
nella Worker
tabella. Ora è impossibile assegnare unWorker
a in Department
in uno Company
e a in un Classification
altro Company
.
Perché è impossibile? È impossibile perché lo schema implementa l'integrità referenziale tra Worker
e Department
e Classification
. Se si tenta di inserire a Worker
per a Department
in Company
e a Classification
di un altro, la combinazione che non esiste nella tabella padre corrispondente attiverà una violazione di integrità referenziale e l'inserimento non funzionerà.
Ecco un diagramma aggiornato di un'implementazione della seconda opzione:
Opzione preferita
Delle due opzioni, preferisco assolutamente la seconda, utilizzando le relazioni identificative e le chiavi a cascata, per due motivi. Innanzitutto, questa opzione raggiunge la regola desiderata senza alcuna programmazione aggiuntiva. Lo sviluppo di un trigger non è banale. Deve essere codificato, testato e mantenuto. Garantire che la logica di trigger sia ottimale in modo da non influire sulle prestazioni non è banale. Il libro Applied Mathematics for Database Professionals fornisce molti dettagli sulla complessità di tale soluzione. In secondo luogo, le regole implicano che un Dipartimento e una Classificazione non possono esistere al di fuori del contesto del Company
, e quindi lo schema ora riflette più accuratamente il mondo reale.
Questa è un'ottima domanda perché mostra esattamente perché semplicemente supporre che ogni tabella richieda una chiave surrogata è una cattiva idea. Fabian Pascal ha un eccellente post sul blog proprio su questo argomento, dimostrando che non solo una chiave surrogata può essere una cattiva idea dal punto di vista dell'integrità dei dati, ma può anche rallentare alcuni recuperia livello fisico proprio perché sono necessari dei join che, se le chiavi fossero state correttamente messe in cascata, non sarebbero necessarie. Un altro argomento interessante che questa domanda rivela è che un database non può garantire che tutti i dati inseriti siano accurati rispetto al mondo reale. Al contrario, può solo garantire che i dati inseriti siano coerenti con le regole che gli sono state dichiarate. In questo caso possiamo fare il meglio possibile usando l'approccio chiave a cascata per garantire che il DBMS possa mantenere i dati coerenti rispetto alla regola secondo cui a Worker
un dato Company
deve essere assegnato un Classification
e uno Department
di quello stesso Company
. Ma, se nel mondo reale Microsoft
ha un dipartimento chiamato Desktop Software
ma l'utente del database afferma che il dipartimento è inveceSoftware Development
il DBMS non può far altro che supporre che gli sia stato dato un dato di fatto.