我的SQL数据库(Firebird)有一个名为 tTransaction 的表。它包含两列, senderFK 和 receiverFK 。还有其他三个表, tBufferStock , tFacility 和 tOutsideLocation 。
发件人或收件人可以是缓冲库存,我们自己的工厂或外部的位置。
我的问题是我不知道如何让 senderFK 或 receiverFK 引用正确的表格。
我想到了发件人和三个可能的发件人之间的新表,其中包含一个ID,表中的数字介于1和3之间以及此表中引用的ID,但实际上这并没有解决问题。有什么想法吗?
诺贝特
答案 0 :(得分:2)
您尝试做的事情无法在SQL中完成。使用单个FK最多不能引用三个不同的表。
您需要做的是:
senderBufferstockFK
,senderFacilityFK
和senderOutsideLocationFK
这意味着,在任何给定时间,三个“fk”列中只有一个可以有一个值,但每个FK列都是特定表的特定FK。
你可以将它直接放到你正在谈论的表中,或者你可以把它外化到一个单独的表中,并从你的主表中引用那个“中间”表,并从那里得到这三个FK
YourTable.SenderFK --> Intermediary.PK
Intermediary.SenderBufferstockFK --> tBufferstock.ID
Intermediary.SenderFacilityFK --> tFacility.ID
Intermediary.SenderOutsideLocationFK --> tOutsideLocation.ID
或者你可以放弃FK关系,但这肯定是 NOT 一个好主意!
马克
答案 1 :(得分:1)
尝试以下架构:
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
)
答案 2 :(得分:1)
SQL不支持“表X中的此列或表Y中的该列”形式的外键。你可以:
重构数据库,以便将所有三个可能的外键表合并为一个,可能称为tCounterParty。如果这些表的结构相同或非常相似,这绝对是合适的。如果它们不相似,您仍然可以采用这种方法,并使用与tCounterParty相关联的其他三个表来保存不同的信息。
如果您的数据库支持,则将您的参照完整性从外键移动到触发器中。
答案 3 :(得分:0)
你不能使用3列作为发送者而3作为接收者吗?所以你将拥有bufferSenderFK,facilitySenderFK和facilitySenderFK。对于单个事务,可以使用1列,其他两个将为null。