Domanda

Il mio database SQL (Firebird) ha una tabella denominata tTransaction . Contiene due colonne, senderFK e receiverFK . Esistono altre tre tabelle, tBufferStock , tFacility e tOutsideLocation .

Un mittente o un destinatario può essere uno stock di buffer, la nostra struttura o una posizione all'esterno.

Il mio problema è che non so come fare in modo che senderFK o receiverFK facciano riferimento alla tabella giusta.

Ho pensato a una nuova tabella tra mittente e tre possibili mittenti con un ID, un numero compreso tra 1 e 3 per la tabella e l'ID di riferimento all'interno di questa tabella, ma in realtà ciò non risolve il problema. Qualche idea?

Norbert

È stato utile?

Soluzione

Quello che stai cercando di fare non può essere fatto in SQL. Non puoi fare riferimento a un massimo di tre diverse tabelle con un singolo FK.

Quello che devi fare sarebbe:

  • crea colonne aggiuntive senderBufferstockFK , senderFacilityFK e senderOutsideLocationFK
  • collegale alle tabelle appropriate
  • hanno un vincolo di controllo (se supportato) o un trigger o qualche altro meccanismo sulla tabella principale per assicurarsi che solo uno di questi tre abbia un valore in qualsiasi momento

Ciò significherebbe, in qualsiasi momento, solo uno dei tre "fk" la colonna potrebbe avere un valore, ma ogni colonna FK sarebbe un FK specifico per una tabella specifica.

Potresti metterlo direttamente nella tabella di cui stai parlando, oppure potresti esternarlo in una tabella separata e dalla tua tabella principale fare semplicemente riferimento a "intermediario". tabella, e da lì hanno questi tre FK

YourTable.SenderFK --> Intermediary.PK
    Intermediary.SenderBufferstockFK --> tBufferstock.ID
    Intermediary.SenderFacilityFK --> tFacility.ID
    Intermediary.SenderOutsideLocationFK --> tOutsideLocation.ID

Oppure puoi semplicemente abbandonare la relazione FK, ma questa è sicuramente NON una buona idea!

Marc

Altri suggerimenti

Prova il seguente schema:

tSenderReceiver (type INT, id INT, PRIMARY KEY (type, id))

tTransaction (id INT PRIMARY KEY, senderType INT, senderId INT, receiverType INT, receiverID INT,
      FOREIGN KEY (senderType, senderID) REFERENCES tSenderReceiver,
      FOREIGN KEY (receiverType, receiverID) REFERENCES tSenderReceiver
)

tBufferStock (type INT, id INT,
      CHECK (type = 1),
      PRIMARY KEY (type, id),
      FOREIGN KEY (type, id) REFERENCES tSenderReceiver
)

tFacility (type INT, id INT,
      CHECK (type = 2),
      PRIMARY KEY (type, id),
      FOREIGN KEY (type, id) REFERENCES tSenderReceiver
)

tOutsideLocation (type INT, id INT,
      CHECK (type = 3),
      PRIMARY KEY (type, id),
      FOREIGN KEY (type, id) REFERENCES tSenderReceiver
)

SQL non supporta una chiave esterna del modulo "o questa colonna nella tabella X o quella colonna nella tabella Y". Puoi:

  1. Rifattorizza il tuo database in modo che tutte e tre le possibili tabelle di chiavi esterne siano combinate in una sola, possibilmente chiamata tCounterParty. Ciò è sicuramente appropriato se la struttura di tali tabelle è identica o molto simile. Se non sono simili, puoi comunque adottare questo approccio e utilizzare altre tre tabelle, collegate a tCounterParty, per contenere le informazioni variabili.

  2. Sposta l'integrità referenziale da una chiave esterna in un trigger, se supportato dal tuo database.

non puoi usare 3 colonne per il mittente e 3 per il destinatario? quindi avrai bufferSenderFK, facilitySenderFK e facilitySenderFK. per una singola transazione, è possibile utilizzare 1 colonna e le altre due saranno null.

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