在多个表中引用主键的外键?

我必须在数据库员工下面有两个表,即employees_ce和employees_sn。

他们都有各自独特的主键列。

我有另一个名为deductions的表,我想要引用employees_ce的主键以及employees_sn的外键列。 这可能吗?

例如

employees_ce -------------- empid name khce1 prince employees_sn ---------------- empid name khsn1 princess 

这是可能的吗?

 deductions -------------- id name khce1 gold khsn1 silver 

假设我已经正确理解了你的场景,这就是我所说的正确方法:

从更高层次的数据库描述开始! 你有雇员,雇员可以是“雇员”雇员和“雇员”雇员(不pipe这些是什么)。 在面向对象方面,有一个“员工”类,有两个子类叫做“ce employee”和“sn employee”。

然后,您将此更高级别的描述转换为三个表: employeesemployees_ceemployees_sn

  • employees(id, name)
  • employees_ce(id, ce-specific stuff)
  • employees_sn(id, sn-specific stuff)

由于所有员工都是员工,所以每个员工在employees表中都会有一行。 “ce”雇员在employees_ce表中也有一行,而“sn”雇员在employees_sn表中也有一行。 employees_ce.idemployees_ce.id的外键,就像employees_sn.id

要引用任何types的雇员(ce或sn),请参阅employees表。 也就是说,你遇到的外键应该参考那张表!

你可能会添加两个外键约束(老实说:我从来没有尝试过),但是它会坚持在两个表中存在父行。

相反,您可能希望为您的两个员工子types创build一个超types,然后将外键指向那里。 (当然,假设你有充分的理由来拆分两种types的员工)。

  employee employees_ce ———————— employees_sn ———————————— type ———————————— empid —————————> empid <——————— empid name /|\ name | | deductions | —————————— | empid ————————+ name 

在雇员表中type将是cesn

其实我自己也是这么做的 我有一个名为“评论”的表,其中包含3个其他表中的logging的评论。 这两个解决scheme实际上都不能处理你可能想要的一切。 在你的情况下,你会这样做:

解决scheme1:

  1. 在employees_ce和employees_sn中添加一个tinyint字段,该字段的默认值在每个表中都是不同的(这个字段表示一个“表标识符”,所以我们称之为tid_ce&tid_sn)

  2. 使用表格的PK和表格ID字段为每个表格创build唯一索引。

  3. 将一个tinyint字段添加到“扣除”表中以存储外键的第二半(表ID)

  4. 在你的“扣除”表中创build2个外键(你不能强制引用完整性,因为任何一个键都是有效的,

     ALTER TABLE [dbo].[Deductions] WITH NOCHECK ADD CONSTRAINT [FK_Deductions_employees_ce] FOREIGN KEY([id], [fk_tid]) REFERENCES [dbo].[employees_ce] ([empid], [tid]) NOT FOR REPLICATION GO ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_ce] GO ALTER TABLE [dbo].[Deductions] WITH NOCHECK ADD CONSTRAINT [FK_Deductions_employees_sn] FOREIGN KEY([id], [fk_tid]) REFERENCES [dbo].[employees_sn] ([empid], [tid]) NOT FOR REPLICATION GO ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_sn] GO employees_ce -------------- empid name tid khce1 prince 1 employees_sn ---------------- empid name tid khsn1 princess 2 deductions ---------------------- id tid name khce1 1 gold khsn1 2 silver ** id + tid creates a unique index ** 

解决scheme2:该解决scheme允许保持参照完整性:1.在“扣减”表中创build第二个外键字段,在两个外键中允许空值,并创build正常的外键:

  employees_ce -------------- empid name khce1 prince employees_sn ---------------- empid name khsn1 princess deductions ---------------------- idce idsn name khce1 *NULL* gold *NULL* khsn1 silver 

只有列不为空时才检查完整性,因此可以保持参照完整性。

我知道这是一个长期停滞不前的话题,但是如果有人在这里search,我是如何处理多表外键的。 使用这种技术,您没有任何DBA强制级联操作,所以请确保您在代码中处理DELETE等。

 Table 1 Fruit pk_fruitid, name 1, apple 2, pear Table 2 Meat Pk_meatid, name 1, beef 2, chicken Table 3 Entity's PK_entityid, anme 1, fruit 2, meat 3, desert Table 4 Basket (Table using fk_s) PK_basketid, fk_entityid, pseudo_entityrow 1, 2, 2 (Chicken - entity denotes meat table, pseudokey denotes row in indictaed table) 2, 1, 1 (Apple) 3, 1, 2 (pear) 4, 3, 1 (cheesecake) 

所以操作的例子看起来像这样

 deductions -------------- type id name 1 khce1 gold 2 khsn1 silver types --------------------- 1 employees_ce 2 employees_sn 

技术上可行。 您可能会在扣除和employees_sn中引用employees_ce。 但为什么不合并employees_sn和employees_ce? 我没有理由为什么你有两张桌子。 没有一对多的关系。 (而不是在这个例子中)很多列。

如果您为一列执行两个引用,则员工必须在两个表中都有一个条目。

是的,这是可能的。 你需要为第三个表定义2个FK。 每个FK指向一个表的必填字段(即每个外表1 FK)。

假设你出于某种原因必须为两个雇员types设置两张表,我将在vmarquez的答案上扩展:

架构:

 employees_ce (id, name) employees_sn (id, name) deductions (id, parentId, parentType, name) 

扣除数据:

 deductions table id parentId parentType name 1 1 ce gold 2 1 sn silver 3 2 sn wood ... 

这将允许您将扣减指向模式中的任何其他表。 这种关系不受数据库级别约束IIRC的支持,因此您必须确保您的应用程序正确pipe理约束(如果您有多个不同的应用程序/服务碰到相同的数据库,这会更加麻烦)。