SQL 数据库(Firebird):外键问题

发布于 2024-08-08 21:45:14 字数 392 浏览 2 评论 0原文

我的 SQL 数据库 (Firebird) 有一个名为 tTransaction 的表。它包含两列:senderFKreceiverFK。还有其他三个表:tBufferStocktFacilitytOutsideLocation

发送者或接收者可以是缓冲库存、我们自己的设施或外部位置。

我的问题是我不知道如何让 senderFKreceiverFK 引用正确的表。

我想过在发件人和三个可能的发件人之间建立一个新表,其中包含一个 ID、该表的 1 到 3 之间的数字以及该表中引用的 ID,但实际上这并不能解决问题。有什么想法吗?

诺伯特

My SQL database (Firebird) has a table named tTransaction. It contains two columns, senderFK and receiverFK. There are three other tables, tBufferStock, tFacility and tOutsideLocation.

A sender or a receiver can be either a buffer stock, our own facility or a location outside.

My problem is that I don't know how to let senderFK or receiverFK reference the right table.

I've thought of a new table between sender and the three possible senders with an ID, a number between 1 and 3 for the table and the referenced ID within this table, but actually that doesn't solve the problem. Any ideas?

Norbert

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

云醉月微眠 2024-08-15 21:45:14

您尝试做的事情无法在 SQL 中完成。您不能使用单个 FK 引用最多三个不同的表。

您需要做的是:

  • 创建附加列 senderBufferstockFKsenderFacilityFKsenderOutsideLocationFK
  • 的相应表
  • 将它们连接到具有检查约束 (如果支持)或主表上的触发器或其他机制,以确保在任何给定时间只有这三个列之一具有值

这意味着,在任何给定时间,三个“fk”列中只有一个可以具有值其上,但每个 FK 列将是特定表的特定 FK。

您可以将其直接放入您正在讨论的表中,或者您可以将其外部化到一个单独的表中,然后从主表中引用该“中间”表,然后从那里得到这三个 FK

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

或者您可以删除 FK -关系,但这绝对不是一个好主意!

马克

What you're trying to do cannot be done in SQL. You cannot reference up to three different tables with a single FK.

What you need to do would be:

  • create additional columns senderBufferstockFK, senderFacilityFK, and senderOutsideLocationFK
  • connect those to the appropriate tables
  • have a check constraint (if supported) or a trigger or some other mechanism on your main table to make sure only one of those three has a value at any given time

This would mean, at any given time, only one of the three "fk" column could have a value on it, but each FK column would be a specific FK to a specific table.

You could put this directly into the table you're talking about, or you could externalize this into a separate table and from your main table just reference that "intermediary" table, and from there have these three FK

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

Or you can just drop the FK-relationship, but that's definitely NOT a good idea!

Marc

哭了丶谁疼 2024-08-15 21:45:14

尝试以下架构:

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
)

Try the following 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
)
清旖 2024-08-15 21:45:14

SQL 不支持“表 X 中的此列或表 Y 中的该列”形式的外键。您可以:

  1. 重构您的数据库,以便将所有三个可能的外键表组合成一个,可能称为 tCounterParty。如果这些表的结构相同或非常相似,这绝对是合适的。如果它们不相似,您仍然可以采用此方法并使用链接到 tCounterParty 的其他三个表来保存变化的信息。

  2. 将引用完整性从外键移至触发器(如果数据库支持)。

SQL does not support a foreign key of the form "either this column in table X or that column in table Y". You can:

  1. Refactor your database so that all three possible foreign key tables are combined into one, possibly called tCounterParty. This is definitely appropriate if the structure of those tables is identical or very similar. If they are not similar you can still take this approach and use three other tables, linked to tCounterParty, to hold the varying information.

  2. Move your referential integrity from a foreign key into a trigger, if supported by your database.

秋意浓 2024-08-15 21:45:14

不能使用 3 列作为发送者,3 列作为接收者吗?因此您将拥有 bufferSenderFK、facilitySenderFK 和facilitySenderFK。对于单个事务,可以使用 1 列,另外两列将为空。

can't you use 3 columns for sender and 3 for receiver? so you'll have bufferSenderFK, facilitySenderFK and facilitySenderFK. for a single transaction, 1 column can be used and other two will be null.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文