Problema di relazione tra entità


19

Ho 4 tabelle correlate in questo modo (è un esempio):

Company:
ID
Name
CNPJ

Department:
ID
Name
Code
ID_Company 

Classification:
ID
Name
Code
ID_Company

Workers:
Id 
Name
Code
ID_Classification
ID_Department

Supponiamo che io abbia un classificationcon id = 20, id_company = 1. E un departmentche ha id_company = 2(che rappresenta un'altra società).

Ciò consentirà la creazione di un lavoratore proveniente da due società poiché la classificazione e il dipartimento sono collegati separatamente alla società. Non voglio che ciò accada, quindi penso di avere un problema con le mie relazioni e non so come risolverlo.


1
Che cos'è la "classificazione"?
Jehad Keriaki,

1
Immagino classificationsia analogo alla posizione, ad esempio segretario, bidello, signore supremo, ecc.
Erik,

Vuoi far valere che un lavoratore deve appartenere allo stesso dipartimento della classificazione?
Lennart,

Forse Dipartimento, Classificazione (e persino Lavoratore) dovrebbero essere visti come entità deboli, tutte dipendenti dalla Società. Quindi la chiave aziendale sarebbe parte delle chiavi del dipartimento, della classificazione e del lavoratore. Un'entità debole è un'entità cui esistenza dipende dall'esistenza di un'altra entità.
miracle173,

Risposte:


9

Il problema deriva dal fatto che manca un tipo di entità nel modello. Considera il seguente ERD:

ERD

Si noti che ho aggiunto un tipo di entità di intersezione tra DEPARTMENTe CLASSIFICATION. Questo nuovo tipo di entità: POSITIONfornisce le informazioni implicite nel tuo modello, secondo cui un determinato reparto ha una serie di lavori di varie classificazioni.

L'aggiunta POSITIONal modello come entità esplicita presenta alcuni vantaggi.

  1. Evita il problema di cui potresti WORKERessere potenzialmente assegnato a dipartimenti e classificazioni in diverse aziende.
  2. Ti dà un locus per altri predicati che potrebbero essere applicabili a una posizione, come il grado di stipendio, ecc.
  3. Ti permette di registrare il fatto che esiste una posizione, anche se non ci sono WORKERs attualmente nella posizione, il che è probabilmente informazioni utili.

Si noti che per evitare il problema di definire una posizione per un dipartimento e una classificazione che si trovano in diverse società, ho ampliato le chiavi di entrambi DEPARTMENTe CLASSIFICATION, il che è buono per i motivi che puoi leggere a lungo nella risposta di Todd Everett.

ATTENZIONE Il modello sopra presuppone una semplificazione. In particolare, presuppone che ciascuna posizione sia registrata una sola volta. Questo può o meno essere adatto alle regole della tua attività. Se sono necessari più POSITIONrecord per lo stesso reparto e la stessa classificazione all'interno di un'azienda, è possibile introdurre una chiave surrogata POSITION.


24

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

inserisci qui la descrizione dell'immagine

Allo stato attuale, potresti avere 2 aziende - diciamo IBMe Microsoft. IBMpuò avere un Software Developmentdipartimento e Microsoft può avere un Desktop Softwaredipartimento. IBM può avere una Software Engineerclassificazione e Microsoft può avere una Software Developerclassificazione. Ora, perché hai una chiave surrogata per Departmente Classification, il fatto che Software Developmentsia un IBMdipartimento ed Desktop Softwareè un Microsoftdipartimento è perso per le future relazioni con i bambini. Questo è anche il caso di Classification. Pertanto è facile assegnare accidentalmente Harlan Mills, chi è un IBMdipendente del Software Developmentdipartimento, una classificazione di Software Developercui è unMicrosoftclassificazione! Allo stesso modo, al lavoratore potrebbe essere data la giusta classificazione e il reparto sbagliato! Ecco un diagramma che mostra il primo esempio:

inserisci qui la descrizione dell'immagine

I 1 ID rappresentano IBMe i 2 ID rappresentano Microsoft. Ho evidenziato in rosso lo scenario in cui Harlan Millse Bill Gatessono 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 Companytabella, che è fondamentale e non ha genitori, quindi creare relazioni di identificazione con le tabelle Departmente Classificationfiglio. Le tabelle Departmente Classificationora hanno un PK di Company Idpiù un numero di sequenza o un nome per distinguerli. Quindi, anche le relazioni da Departmente Classificationper Workerdiventare identifyinge quindi il PK di Workerdiventa 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 Idnella Workertabella. Ora è impossibile assegnare unWorkera in Departmentin uno Companye a in un Classificationaltro Company.

Perché è impossibile? È impossibile perché lo schema implementa l'integrità referenziale tra Workere Departmente Classification. Se si tenta di inserire a Workerper a Departmentin Companye a Classificationdi 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: inserisci qui la descrizione dell'immagine

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 Workerun dato Companydeve essere assegnato un Classificatione uno Departmentdi quello stesso Company. Ma, se nel mondo reale Microsoftha un dipartimento chiamato Desktop Softwarema 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.


1

Il modo in cui capisco la domanda è che il campo ID_Classification della tabella 'Workers' dovrebbe consentire solo le classificazioni definite per la rispettiva azienda del lavoratore. Pertanto, la convalida (allegando una REGOLA o tramite TRIGGERS) le informazioni inserite / aggiornate nel campo Workers.ID_Classification è adeguata per soddisfare questo requisito.


1

Dalle mie letture, non capisco ancora cosa sia questa classificazione e perché debba avere ID_Company . Se è come una posizione come qualcuno menzionato qui, penso che una tabella statica per contenere tutte le posizioni sarebbe meglio.

Se lo stai facendo per trovare facilmente una classificazione / posizione in una società, aggiungi una semplice query / vista per collegare i dipartimenti-lavoratori-classificazione e recuperare l'ID azienda della classificazione.

al giorno d'oggi, ci sono viste o tecnologie più intelligenti come viste materializzate e unire indici, quindi se il tuo problema è l'esecuzione della query, usali.

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.