Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 外键在多个表中引用主键?_Sql_Foreign Keys_Primary Key - Fatal编程技术网

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

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

我必须在数据库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
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列键可以帮助