Sql 外键在多个表中引用主键?
我必须在数据库employees下创建两个表,即employees\u ce和employees\u sn 它们都有各自独特的主键列 我有另一个名为Decretions的表,我想引用employees\u ce和employees\u sn的主键作为其外键列。这可能吗Sql 外键在多个表中引用主键?,sql,foreign-keys,primary-key,Sql,Foreign Keys,Primary Key,我必须在数据库employees下创建两个表,即employees\u ce和employees\u sn 它们都有各自独特的主键列 我有另一个名为Decretions的表,我想引用employees\u ce和employees\u sn的主键作为其外键列。这可能吗 deductions -------------- id name khce1 gold khsn1 silver 比如说 employees_ce -------------- empid name kh
deductions
--------------
id name
khce1 gold
khsn1 silver
比如说
employees_ce
--------------
empid name
khce1 prince
employees_sn
----------------
empid name
khsn1 princess
那么这可能吗
deductions
--------------
id name
khce1 gold
khsn1 silver
技术上可能。您可能会在扣减和员工编号中引用员工。但是为什么不合并员工和员工呢?我看不出你们有两张桌子的理由。没有一对多的关系。和(本例中没有)许多列
如果对一列进行两次引用,则员工必须在两个表中都有一个条目。是的,这是可能的。您需要为第三个表定义2个FK。每个FK指向一个表的必填字段(即每个外部表1个FK)。您可能可以添加两个外键约束(老实说:我从未尝试过),但它会坚持两个表中都存在父行 相反,您可能希望为两个雇员子类型创建一个超类型,然后将外键指向那里。(当然,假设你有充分的理由将这两类员工分开)
员工
员工-----员工
------------类型------------
empid----------->empid假设我正确理解了您的场景,这就是我所说的正确方法:
从更高层次的数据库描述开始!您有员工,员工可以是“ce”员工和“sn”员工(无论是什么)。在面向对象的术语中,有一个类“employee”,有两个子类“ce employee”和“sn employee”
然后将此更高级别的描述转换为三个表:employees
、employees\u ce
和employees\u sn
:
员工(身份证、姓名)
employees\u ce(id、ce特定的内容)
employees\u序列号(id、序列号特定的内容)
因为所有员工都是员工(duh!),所以每个员工都会在employees
表中有一行。“ce”员工在employees\u ce
表中也有一行,“sn”员工在employees\u sn
表中也有一行employees\u ce.id
是employees.id
的外键,就像employees\u ce.id
一样
要提及任何类型的员工(ce或sn),请参阅员工表。也就是说,您遇到问题的外键应该参考该表 假设出于某种原因,两种员工类型必须有两个表,我将扩展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,因此您必须确保您的应用程序正确管理约束(如果您有多个不同的应用程序/服务访问同一个数据库,则会变得更加麻烦)。实际上,我自己也这样做。我有一个名为“Comments”的表,其中包含其他3个表中记录的注释。这两种解决方案实际上都无法处理您可能希望它处理的所有问题。在您的情况下,您可以这样做:
解决方案1:
向employees\u ce和employees\u sn添加一个tinyint字段,该字段在每个表中具有不同的默认值(此字段表示“表标识符”,因此我们将其称为tid\u ce&tid\u sn)
使用表的PK和表id字段在每个表上创建唯一索引
将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.在“扣减”表中创建第二个外键字段,在两个外键中允许空值,并创建普通外键:
employees_ce
--------------
empid name
khce1 prince
employees_sn
----------------
empid name
khsn1 princess
deductions
----------------------
idce idsn name
khce1 *NULL* gold
*NULL* khsn1 silver
只有当列不为null时,才会检查完整性,因此您可以保持引用完整性。我知道这是一个长期停滞的主题,但如果有人在这里搜索,我将如何处理多表外键。使用此技术,您没有任何DBA强制执行的级联操作,因此请确保您处理删除在你的代码中有这样的代码
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)
Op的例子是这样的
deductions
--------------
type id name
1 khce1 gold
2 khsn1 silver
types
---------------------
1 employees_ce
2 employees_sn
我尝试添加多个外键,它们都起作用了,但是,在添加记录时,java derby告诉我两个外键约束都被违反了!我刚刚在PostgreSQL上尝试了它,它在那里起作用。两个表中都有父记录吗?父记录你的意思是empid?问题肯定已经从“扣减”转移到了“扣减”上“雇员”的表格表。如何根据类型引用可能不同的实体?@gawpertron:嗯,empid在所有类型中都是唯一的。您可以使用“类型”字段查看需要引用的子表。或者,如果子表足够少,则只需将它们左键联接。如果不使用“employee”基表,则主键无法e声明(因为它可能引用表A或表B或…);现在可以了。将员工_ce
和员工_sn
分开的智慧是假设的,并且注意到了这个假设。你如何使ce和sn相互排斥?既然员工不能同时是ce和sn,那么最好在数据库中反映出来。我现在有这个问题。我认为e列键可以帮助