Frage

My SQL-Datenbank (Firebird) eine Tabelle mit dem Namen tTransaction . Es enthält zwei Spalten, senderFK und receiverFK . Es gibt drei weitere Tische, tBufferStock tFacility und tOutsideLocation .

Ein Sender oder ein Empfänger kann entweder einen Pufferbestand, unsere eigene Anlage oder einen Ort außerhalb sein.

Mein Problem ist, dass ich weiß nicht, wie lassen senderFK oder receiverFK verweist auf die rechte Tabelle.

Ich habe gedacht, eine neue Tabelle zwischen Sender und den drei möglichen Sendern mit einer ID, einer Zahl zwischen 1 und 3 für die Tabelle und die referenzierte ID innerhalb dieser Tabelle, aber das eigentlich nicht das Problem lösen. Irgendwelche Ideen?

Norbert

War es hilfreich?

Lösung

Was Sie versuchen können zu tun, nicht in SQL erfolgen. Sie können nicht bis zu drei verschiedenen Tabellen mit einer einzigen FK verweisen.

Was Sie tun müssen, wäre:

  • erstellen zusätzliche Spalten senderBufferstockFK, senderFacilityFK und senderOutsideLocationFK
  • verbinden, die zu den entsprechenden Tabellen
  • eine Check-Bedingung hat (falls unterstützt) oder einen Trigger oder einen anderen Mechanismus auf Ihrer Haupt-Tabelle, um sicherzustellen, nur einer von denen drei einen Wert zu einem bestimmten Zeitpunkt hat

Dies würde bedeuten, zu einem bestimmten Zeitpunkt nur eine der drei „fk“ Spalte könnte einen Wert drauf hat, aber jede FK Spalte eine bestimmte FK mit einer bestimmten Tabelle sein würde.

Sie können dies Sie sprechen direkt in den Tisch legen, oder Sie können diese in einer separaten Tabelle externalisieren und aus Ihrer Haupttabelle, dass „Vermittler“ Tabelle nur Referenz, und von dort haben diese drei FK

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

Sie können auch die FK-Beziehung nur fallen, aber das ist auf jeden Fall nicht eine gute Idee!

Marc

Andere Tipps

Versuchen Sie das folgende 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 keinen Fremdschlüssel in der Form „entweder diese Spalte in der Tabelle X oder die Spalte in der Tabelle Y“ unterstützen. Sie können:

  1. Refaktorieren Datenbank, so dass alle drei möglichen Fremdschlüsseltabellen zu einem zusammengefasst werden, möglicherweise tCounterParty genannt. Dies ist auf jeden Fall sinnvoll, wenn die Struktur dieser Tabellen ist identisch oder sehr ähnlich. Wenn sie nicht ähnlich sind, können Sie immer noch diesen Ansatz und drei weitere Tabellen verwenden, um tCounterParty verknüpft, die unterschiedlichen Informationen zu halten.

  2. Bewegen Sie die referentielle Integrität von einem Fremdschlüssel in einen Trigger, wenn sie von Ihrer Datenbank unterstützt.

Sie können 3 Spalten nicht für Absender verwenden und 3 für Empfänger? so werden Sie bufferSenderFK, facilitySenderFK und facilitySenderFK haben. für eine einzelne Transaktion kann 1-Säule verwendet werden, und die beiden anderen wird null sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top