Chiave esterna riferita a chiavi primarie su più tabelle?

Ho due tabelle in particolare dipendenti_ce e dipendenti_sn sotto gli impiegati del database.

Entrambi hanno le rispettive colonne di chiave primaria univoche.

Ho un’altra tabella chiamata deduzioni, la cui colonna chiave esterna voglio fare riferimento alle chiavi primarie di employees_ce e dipendenti_sn. È ansible?

per esempio

employees_ce -------------- empid name khce1 prince employees_sn ---------------- empid name khsn1 princess 

quindi è ansible?

     deductions -------------- id name khce1 gold khsn1 silver 

    Supponendo di aver capito correttamente il tuo scenario, questo è quello che chiamerei il modo giusto per farlo:

    Inizia da una descrizione di livello superiore del tuo database! Avete dipendenti e dipendenti possono essere dipendenti “ce” e dipendenti “sn” (qualunque essi siano). In termini orientati agli oggetti, esiste un “dipendente” di class, con due sottoclassi chiamate “dipendente di ceo” e “impiegato di sn”.

    Quindi traduci questa descrizione di livello superiore in tre tabelle: employees , employees_ce e employees_sn :

    • employees(id, name)
    • employees_ce(id, ce-specific stuff)
    • employees_sn(id, sn-specific stuff)

    Poiché tutti i dipendenti sono dipendenti (duh!), Ogni dipendente avrà una riga nella tabella dei employees . Anche i dipendenti “ce” hanno una riga nella tabella employees_ce e anche i dipendenti “sn” hanno una riga nella tabella employees_sn . employees_ce.id è una chiave esterna per employees.id , proprio come employees_sn.id .

    Per fare riferimento a un dipendente di qualsiasi tipo (ce o sn), fare riferimento alla tabella dei employees . Cioè, la chiave estranea con cui hai avuto problemi dovrebbe fare riferimento a quel tavolo!

    Probabilmente potresti aggiungere due vincoli di chiave esterna (onestamente: non l’ho mai provato), ma insisteremmo sulla presenza della riga genitore in entrambe le tabelle.

    Invece, probabilmente vorrai creare un supertipo per i tuoi due sottotipi di dipendenti, quindi indirizzare la chiave esterna lì. (Supponendo che tu abbia una buona ragione per dividere i due tipi di dipendenti, ovviamente).

      employee employees_ce ———————— employees_sn ———————————— type ———————————— empid —————————> empid <——————— empid name /|\ name | | deductions | —————————— | empid ————————+ name 

    type nella tabella dei dipendenti sarebbe ce o sn .

    In realtà lo faccio da solo. Ho una tabella chiamata ‘Commenti’ che contiene commenti per i record in altri 3 tavoli. Nessuna delle due soluzioni gestisce effettivamente tutto ciò che vorreste probabilmente. Nel tuo caso, lo faresti:

    Soluzione 1:

    1. Aggiungi un campo tinyint a dipendenti_ce e dipendenti_sn che ha un valore predefinito diverso in ogni tabella (Questo campo rappresenta un ‘identificatore di tabella’, quindi li chiameremo tid_ce e tid_sn)

    2. Crea un indice univoco su ogni tabella utilizzando il PK della tabella e il campo ID della tabella.

    3. Aggiungi un campo minuscolo alla tabella ‘Deduzioni’ per memorizzare la seconda metà della chiave esterna (l’ID tabella)

    4. Crea 2 chiavi esterne nella tabella “Deduzioni” (non puoi imporre l’integrità referenziale, perché una delle due chiavi sarà valida o l’altra … ma mai entrambe:

       ALTER TABLE [dbo].[Deductions] WITH NOCHECK ADD CONSTRAINT [FK_Deductions_employees_ce] FOREIGN KEY([id], [fk_tid]) REFERENCES [dbo].[employees_ce] ([empid], [tid]) NOT FOR REPLICATION GO ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_ce] GO ALTER TABLE [dbo].[Deductions] WITH NOCHECK ADD CONSTRAINT [FK_Deductions_employees_sn] FOREIGN KEY([id], [fk_tid]) REFERENCES [dbo].[employees_sn] ([empid], [tid]) NOT FOR REPLICATION GO ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_sn] GO employees_ce -------------- empid name tid khce1 prince 1 employees_sn ---------------- empid name tid khsn1 princess 2 deductions ---------------------- id tid name khce1 1 gold khsn1 2 silver ** id + tid creates a unique index ** 

    Soluzione 2: questa soluzione consente di mantenere l’integrità referenziale: 1. Creare un secondo campo chiave esterna nella tabella ‘Deduzioni’, consentire valori Null in entrambe le chiavi esterne e creare normali chiavi esterne:

      employees_ce -------------- empid name khce1 prince employees_sn ---------------- empid name khsn1 princess deductions ---------------------- idce idsn name khce1 *NULL* gold *NULL* khsn1 silver 

    L’integrità viene controllata solo se la colonna non è nulla, quindi è ansible mantenere l’integrità referenziale.

    So che questo è un argomento lungo stagnante, ma nel caso in cui qualcuno cerca qui è come mi occupo di chiavi esterne multi tabella. Con questa tecnica non hai alcuna operazione di cascata forzata DBA, quindi assicurati di occuparti di DELETE e del codice.

     Table 1 Fruit pk_fruitid, name 1, apple 2, pear Table 2 Meat Pk_meatid, name 1, beef 2, chicken Table 3 Entity's PK_entityid, anme 1, fruit 2, meat 3, desert Table 4 Basket (Table using fk_s) PK_basketid, fk_entityid, pseudo_entityrow 1, 2, 2 (Chicken - entity denotes meat table, pseudokey denotes row in indictaed table) 2, 1, 1 (Apple) 3, 1, 2 (pear) 4, 3, 1 (cheesecake) 

    L’esempio di SO sarebbe simile a questo

     deductions -------------- type id name 1 khce1 gold 2 khsn1 silver types --------------------- 1 employees_ce 2 employees_sn 

    Tecnicamente ansible. Probabilmente farai riferimento a dipendenti_ce in deduzioni e dipendenti_sn. Ma perché non unire dipendenti_sn e dipendenti_ce? Non vedo alcun motivo per cui hai due tavoli. Nessuno a molte relazioni. E (non in questo esempio) molte colonne.

    Se si fanno due riferimenti per una colonna, un dipendente deve avere una voce in entrambe le tabelle.

    Sì, è ansible. Dovrai definire 2 FK per la 3a tabella. Ogni FK che punta ai campi richiesti di una tabella (cioè 1 FK per tabella esterna).

    Supponendo che tu debba avere due tabelle per i due tipi di dipendenti per qualche ragione, mi dilungherò sulla risposta di vmarquez:

    Schema:

     employees_ce (id, name) employees_sn (id, name) deductions (id, parentId, parentType, name) 

    Dati in detrazioni:

     deductions table id parentId parentType name 1 1 ce gold 2 1 sn silver 3 2 sn wood ... 

    Ciò consentirebbe di avere punti di detrazione per qualsiasi altra tabella nello schema. Questo tipo di relazione non è supportata da vincoli a livello di database, IIRC quindi dovrai assicurarti che la tua App gestisca correttamente il vincolo (che lo rende più complicato se hai diverse app / servizi che colpiscono lo stesso database).