我必须在数据库员工下面有两个表,即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
答案 0 :(得分:91)
假设我已正确理解您的场景,我就称之为正确的方式来执行此操作:
从数据库的更高级别描述开始!您有员工,员工可以是“ce”员工和“sn”员工(无论是那些员工)。在面向对象的术语中,有一个类“employee”,有两个子类叫做“ce employee”和“sn employee”。
然后,您将此更高级别的说明翻译为三个表格:employees
,employees_ce
和employees_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.id
是[{1}}的外键,就像employees.id
一样。
要引用任何类型的员工(ce或sn),请参阅employees_sn.id
表。也就是说,您遇到问题的外键应该参考该表!
答案 1 :(得分:22)
你可以添加两个外键约束(老实说:我从来没有尝试过),但它坚持在两个表中都存在父行。
相反,您可能希望为两个员工子类型创建一个超类型,然后将外键指向那里。 (当然,假设你有充分的理由将这两类员工分开)。
employee
employees_ce ———————— employees_sn
———————————— type ————————————
empid —————————> empid <——————— empid
name /|\ name
|
|
deductions |
—————————— |
empid ————————+
name
员工表中的 type
为ce
或sn
。
答案 2 :(得分:18)
其实我自己这样做。我有一个名为'Comments'的表,其中包含3个其他表中记录的注释。这两种解决方案都没有真正处理您可能想要的一切。在你的情况下,你会这样做:
解决方案1:
在employees_ce和employees_sn中添加一个tinyint字段,其默认值在每个表中都不同(此字段表示'表标识符',因此我们将其称为tid_ce&amp; tid_sn)
使用表的PK和表ID字段在每个表上创建唯一索引。
在'Deductions'表中添加tinyint字段以存储外键的后半部分(表ID)
在“扣减”表格中创建2个外键(您无法强制执行参照完整性,因为其中一个键有效或另一个...但从不同时:
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 **
解决方案2: 此解决方案允许维护参照完整性: 1.在“Deductions”表中创建第二个外键字段,允许两个外键中的Null值,并创建正常的外键:
employees_ce
--------------
empid name
khce1 prince
employees_sn
----------------
empid name
khsn1 princess
deductions
----------------------
idce idsn name
khce1 *NULL* gold
*NULL* khsn1 silver
只有在列不为空时才会检查完整性,因此您可以保持参照完整性。
答案 3 :(得分:6)
我知道这是一个长期停滞的话题,但是如果有人在这里搜索我是如何处理多表外键的。使用此技术,您没有任何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)
SO Op的示例看起来像这样
deductions
--------------
type id name
1 khce1 gold
2 khsn1 silver
types
---------------------
1 employees_ce
2 employees_sn
答案 4 :(得分:1)
技术上可行。您可能会在扣减和employees_sn中引用employees_ce。但是你为什么不合并employees_sn和employees_ce?我没有理由说你有两张桌子。无人关系。而且(不是在这个例子中)很多列。
如果您对一列进行两次引用,则员工必须在两个表中都有一个条目。
答案 5 :(得分:1)
是的,有可能。您需要为第3个表定义2个FK。每个FK指向一个表的必需字段(即每个外表的1 FK)。
答案 6 :(得分:0)
假设由于某种原因您必须为两种员工类型设置两个表,我将继续讨论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不支持这种关系,因此您必须确保您的应用程序正确管理约束(如果您有多个不同的应用程序/服务访问同一个数据库,这会使其更加麻烦)。 / p>