Question

Ma base de données SQL (Firebird) contient une table nommée tTransaction . Il contient deux colonnes, senderFK et receiverFK . Il existe trois autres tables, tBufferStock , tFacility et tOutsideLocation .

Un expéditeur ou un destinataire peut être un stock tampon, notre propre installation ou un lieu situé à l'extérieur.

Mon problème est que je ne sais pas comment laisser senderFK ou receiverFK référencer le tableau de droite.

J'ai pensé à une nouvelle table entre l'expéditeur et les trois expéditeurs possibles avec un ID, un nombre compris entre 1 et 3 pour la table et l'ID référencé dans cette table, mais en réalité cela ne résout pas le problème. Des idées?

Norbert

Était-ce utile?

La solution

Ce que vous essayez de faire ne peut pas être fait en SQL. Vous ne pouvez pas référencer jusqu'à trois tables différentes avec un seul FK.

Ce que vous devez faire serait:

  • créer des colonnes supplémentaires senderBufferstockFK , senderFacilityFK et senderOutsideLocationFK
  • connectez-les aux tables appropriées
  • utilisez une contrainte de vérification (si elle est prise en charge), un déclencheur ou un autre mécanisme sur votre table principale pour vous assurer qu'un seul de ces trois facteurs a une valeur à un moment donné

Cela signifierait, à tout moment, que l’un des trois "fk" colonne pourrait avoir une valeur, mais chaque colonne FK serait un FK spécifique à une table spécifique.

Vous pouvez le placer directement dans la table dont vous parlez ou l'externaliser dans une table distincte et, à partir de votre table principale, référencer simplement cet "intermédiaire". table, et à partir de là ont ces trois FK

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

Ou vous pouvez simplement laisser tomber la relation FK, mais c'est PAS une bonne idée!

Marc

Autres conseils

Essayez le schéma suivant:

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 ne prend pas en charge une clé étrangère de la forme "cette colonne de la table X ou cette colonne de la table Y". Vous pouvez:

  1. Refactorisez votre base de données afin que les trois tables de clé étrangère possibles soient combinées en une seule, éventuellement appelée tCounterParty. Cela convient parfaitement si la structure de ces tableaux est identique ou très similaire. Si elles ne sont pas similaires, vous pouvez quand même adopter cette approche et utiliser trois autres tables, liées au tCounterParty, pour stocker les informations variables.

  2. Déplacez votre intégrité référentielle d'une clé étrangère vers un déclencheur, si cette base de données le prend en charge.

ne pouvez-vous pas utiliser 3 colonnes pour l'expéditeur et 3 pour le récepteur? vous aurez donc bufferSenderFK, facilitySenderFK et facilitySenderFK. pour une transaction unique, 1 colonne peut être utilisée et deux autres seront nulles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top