选择在两个表之间附加外键的位置?

时间:2009-12-14 15:17:52

标签: sql-server database-design

我有一个采购订单表和另一个表,用于包含特定药品采购订单中的项目。

示例:

PO_Table (POId, MainPharmacyID, SupplierID, PreparedBy)
PO_Items_Table (POItemID, ...)

我有两个选项可以选择链接到哪个表,它们似乎都有效。我已经做了很多次,并且已经完成了这两种方式。

  • 我很想知道他们是否有任何附加外国人的规则?
  • 在我的情况下,我在哪里附上我的外键?

更新

我的两个选择是将POItemID放入PO_Table或将POId放入PO_Items_Table。

更新2:

假设两个表之间的关系是一对一的关系

4 个答案:

答案 0 :(得分:3)

只需指向引用表的PRIMARY KEY

PO_Table (POId PRIMARY KEY, MainPharmacyID, SupplierID, PreparedBy)
PO_Items_Table (POItemID, POId FOREIGN KEY REFERENCES PO_Table (POId), ...)

实际上,在你的PO_Table中我除了POId之外没有看到任何其他候选键,所以现在这似乎是我唯一可用的解决方案。

您正在考虑的“两个选项”是什么?

<强>更新

POItemID放在PO_Table中不是一个选项,除非您希望订单中的订单不超过一个。

请仔细研究一下:如果您只有一列可以在订单表中存储订购商品的id,那么您将在哪里存储其他商品?

更新2:

如果存在一对一关系,通常只需合并表:将两个表中的所有字段合并为一个记录。

但是,有时您需要拆分表格。比如,其中一个实体很少被定义,但是有太多的字段。

在这种情况下,您为第二个实体创建一个单独的关系,并使其PRIMARY KEY列也为FOREIGN KEY

让我们设想一个描述锁和密钥的模型,并且密钥不能重复(因此一个锁最多匹配一个密钥,反之亦然):

Pairs (PairID PRIMARY KEY, LockID UNIQUE, LockProductionDate, KeyId UNIQUE, KeyProductionDate)

如果没有锁定密钥或没有锁定密钥,我们只需将NULLS放入相应的字段中。

但是,如果所有密钥都有锁,但只有少数锁有密钥,我们可以拆分表:

Locks (LockID PRIMARY KEY, LockProductionDate, KeyID UNIQUE)
Keys (KeyID PRIMARY KEY, KeyProductionDate, FOREIGN KEY (KeyID) REFERENCES Locks (KeyID))

如您所见,KeyIDPRIMARY KEY表格中都是FOREIGN KEYKeys

您可能希望在我的博客中阅读此文章:

,描述了将ER模型(实体和关系)映射到关系模型(表和外键)的一些方法

答案 1 :(得分:3)

您没有两个选项..外键约束必须附加到其中包含外键的表(和列)。它必须引用(或指向)另一个表中的主键。当你说你已经多次这样做时,我不太明白你的意思......还有什么方法?

答案 2 :(得分:1)

看起来PO_TablePO_Items_Table的逻辑父级,这意味着PO_Table的主键应该用作项目表中的外键

答案 3 :(得分:0)

如果PO代表“采购订单”而PO项代表采购订单的单个行项目,那么您只能选择如何设置外键。每个采购订单可能有许多项目,但每个项目只有一个采购订单。在这种情况下,Quassnoi给出了正确的设计。

作为一个侧面,每次我设计一个采购订单数据库时,我都使Items表具有由POID和ItemID组成的复合主键。但ItemID在所有项目中并不唯一,只是属于单个PO的项目。每次我开始新的PO时,我都会重新开始,ItemID等于1。这允许我稍后重建采购订单,并以与首次创建订单时相同的顺序获取项目。对于大多数数据处理来说,这是一个微不足道的事情,但是如果它们稍后看起来像一个PO,它可以驱使客户疯狂,并且这些项目不按顺序排列,因为它们感知序列。