Domanda

Qual è il modo migliore per modellare quanto segue ...

Supponi di avere due oggetti: Agency e Publisher , ed entrambi hanno una relazione da 1 a n con Employee . Questa è una vera relazione da 1 a n, poiché ogni dipendente può funzionare solo per un agenzia o un editore . Supponiamo inoltre che non sia possibile presentare a supertipo (ad es. Employer ) che detiene la relazione 1-to-n.

La mia soluzione preferita è avere una chiave esterna in Employee che può collegarsi a una chiave primaria di Agency o Publisher (tutti i miei le chiavi primarie sono ID a 64 bit univoci nel database). Tuttavia, ora non sarò in grado di mappare un'associazione bidirezionale, senza indicare in Employee se si tratta di una relazione Agency o Publisher .

L'altra mia opzione è quella di utilizzare due tabelle, AgencyEmployee e PublisherEmployee , che possono quindi essere collegate come tradizionali associazioni bidirezionali da 1 a n.

Quali consideri le migliori pratiche in questa situazione?

AGGIORNAMENTO: Grazie per le ottime risposte in così poco tempo! Cosa ne pensi della seguente soluzione: chiavi esterne in Employee sia per Agency che per Publisher , come agency_id e publisher_id ?

È stato utile?

Soluzione

La migliore pratica sarebbe probabilmente quella di introdurre una classe Employer.

Dividere il dipendente in AgencyEmployee e PublisherEmployee, d'altra parte, sarebbe una cosa negativa da fare.

Se l'introduzione del datore di lavoro fosse fuori questione, indicherei il tipo di datore di lavoro (agenzia o editore) in Dipendente.

Risposta alla domanda aggiornata:

Questa è un'opzione, ma Employer_type è migliore perché:

  1. In futuro potresti voler aggiungere altri tipi di datori di lavoro
  2. Ci sarà un campo vuoto in ogni riga della tabella Employees.

Altri suggerimenti

Suoni del genere potrebbero essere modellati come una relazione ternaria . Scopri se ti piace l'approccio adottato in questo articolo MSDN.

Ho usato questo approccio:

Employee.EmployerType ('AGENCY' o 'PUBLISHER')

Employee.EmployerID (AgencyID o PublisherID)

Funziona bene, ma è necessaria un'istruzione case in molti dei tuoi SQL. Inoltre, se stai utilizzando un ORM perdi la relazione FK.

Sto trasferendo la maggior parte del mio codice nelle relazioni n: m in modo da poter sfruttare il nostro supporto FK ORM.

Chiaramente sarebbe preferibile un'entità Employer, ma altrimenti ...

Avere AgencyEmployee & amp; Le tabelle PublisherEmployee indicano che sarà difficile determinare se un dipendente appartiene a una categoria o a un'altra.

Quindi, invece, aggiungerei la colonna EmployerType alla tabella Employees; aggiunge un po 'di complessità in più alle tue successive query SQL, ma funziona entro i limiti che hai dato.

Per interesse, perché dovresti essere in grado di aggiungere AgencyEmployee & amp; Tabelle PublisherEmployee, ma non aggiungere una tabella Employer? Solo curioso ...

Un +1 per Can Berk Güder.

Tecnicamente, l'introduzione di un supertipo Datore di lavoro significa che si introduce una relazione Datore di lavoro con tutti gli attributi comuni a Agenzia ed editore, una relazione Specifico dell'Agenzia (non sicuro su come chiamarlo) con la chiave Datore di lavoro e tutti gli attributi specifici dell'Agenzia e la chiave Datore di lavoro come chiave esterna, quindi Agency come query o vista che si unisce a AgencySpecific con Employer e allo stesso modo per Publisher.

Potrebbe essere un po 'complicato avere i dati dell'agenzia e del publisher distribuiti su due tabelle a cui devi unirti ogni volta, ma l'alternativa è scrivere la maggior parte delle tue domande relative ai dipendenti due volte, una volta usando l'agenzia e una volta usando l'editore, e quindi fabbricare i loro sindacati per unire i risultati. (Non ho visto un generatore di query che aiuti con cose di base come questa.) Ho dovuto farlo per un progetto che utilizzava il "nessun supertipo". approccio e non voglio farlo di nuovo.

Le relazioni ternarie BTW e anche le relazioni n-to-n non sono una buona pratica di progettazione se me lo chiedi. Utilizzo delle sole funzioni (ovvero 1-a-n e 1-a-1) ad es. i vincoli diventano molto più facili da formulare.

La mia preferenza personale sarebbe quella di avere una tabella che tu presumi espressamente non possa essere utilizzata (il SuperType di agenzia ed editore; datore di lavoro)

Una semplice alternativa sarebbe semplicemente non applicare il vincolo di chiave esterna. Ciò non è necessariamente problematico, a condizione che tutte le modifiche alla struttura dei dati vengano eseguite tramite Stored Procedure che controlli.

La mia preferenza finale sarebbe simile al tuo suggerimento, di avere una tabella per i dipendenti dell'agenzia e una per i dipendenti degli editori. Ma lo separerei un ulteriore passo avanti ...

Table1: Agency              (id, name, etc)
Table2: Publisher           (id, name, etc)
Table3: Employee            (id, name, etc)
Table4: AgencyEmployees     (agency_id, employee_id)
Table5: PublisherEmployees  (publisher_id, employee_id)


Uno dei motivi per cui lo farei è che diventa banale rendere questo tempo dipendente. I dipendenti iniziano, escono e si spostano tra le aziende. La seguente leggera modifica a quanto sopra ti consentirebbe di rintracciarla ...

Table1: Agency              (id, name, etc)
Table2: Publisher           (id, name, etc)
Table3: Employee            (id, name, etc)
Table4: AgencyEmployees     (agency_id,    employee_id, start_date, leave_date)
Table5: PublisherEmployees  (publisher_id, employee_id, start_date, leave_date)

Questo non impone 1 datore di lavoro per dipendente alla volta, ma può essere applicato dalle procedure memorizzate, dalla GUI, ecc ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top