代码之家  ›  专栏  ›  技术社区  ›  Chrisb

复合外键问题

  •  1
  • Chrisb  · 技术社区  · 15 年前

    我正在尝试找出是否可以用这种方式创建一个外键。

    首先,在这个场景中有两个父表。

    表1有一个pk int和另一个int列。两者结合时是独一无二的。

    表2有一个pk int和另一个int列。两者结合时是独一无二的。

    这两个整数之间的成对值是我们当前为两个表选择子记录的方式。

    表3具有前两个表之一的pk和其他int列的值。它是可靠的可选择的,因为在搜索中使用的这两个字段对上述其中一个表都是唯一的。

    所以我想为这个场景创建一个FK或者可能是两个FK。我希望能够将第一个表中的任何一个表的删除级联到第三个表中,并且还希望将其用于实体框架中的实体关系。

    如果这不合理,请告诉我。我已经读了好几遍了,而且尽可能清楚。

    谢谢

    3 回复  |  直到 15 年前
        1
  •  0
  •   Mark Brackett    15 年前

    如果表3包含表1联合表2中的所有值,则 inheritance scheme :

    Table3 { (int id, int type) PK }
    Table1 { (int id, int type [CHECK type = 1]) FK Table3 }
    Table2 { (int id, int type [CHECK type = 2]) FK Table3 }
    

    这样,从表3中删除将相应地级联到表1或表2。

    否则,如果表3只是表1联合表2的一个子集,那么将表4作为完整集引入即可。

    Table4 { (int id, int type [CHECK type IN (1,2)]) PK }
    Table1 { (int id, int type [CHECK type = 1]) FK Table4 }
    Table2 { (int id, int type [CHECK type = 2]) FK Table4 }
    Table3 { (int id, int type) FK Table4 }
    

    但是,要处理级联删除,您需要从表4中删除(尽管您可以在表3上做一个触发器来为您处理这一点)。

    编辑(因为我认为这是一个重要的观点,应该与评论分开):

    是的,问题是一个和两个是父母。它们在3中都有相关的记录,这将是一个fk,而不是该表的pk。使用FK约束似乎几乎不可能。感谢您的回复!克里斯布(一小时前)

    IMO-你的数据模型就坏了。表1和表2是不相关的,但您试图将它们塞入表3中的同一列中。如果表1和表2以某种方式相关,那么您需要对其建模。

    如果父表(表4)相关,则引入父表;如果父表(表1-FK、表2-FK)相关,则引入第2列;如果父表(表1-FK、表2-FK)不相关,则引入2个联接表。不要试图把一个圆钉子放进一个方孔里,也不要试图用扳机来弥补它。;)

        2
  •  1
  •   Elie    15 年前

    如果我理解正确,您有三个表,结构如下:

    TABLE_A:
        PK_FIELD int NOT NULL
        OTHER_FIELD int NOT NULL, NOT IN TABLE_B.OTHER_FIELD
    
    TABLE_B:
        PK_FIELD int NOT NULL
        OTHER_FIELD int NOT NULL, NOT IN TABLE_A.OTHER_FIELD
    
    TABLE_C:
        PK_FIELD int NOT NULL
        OTHER_FIELD int NOT NULL IN (TABLE_A.OTHER_FIELD OR TABLE_B.OTHER_FIELD
    

    您要做的是定义表,这样您就可以在表之间级联更新和删除。因为怎样 TABLE_A.OTHER_FIELD TABLE_B.OTHER_FIELD 定义后,您将保证它们之间没有重叠。问题是找出哪个表引用了 TABLE_C .

    你能用这个定义做的是从 TABLE_A TABLE_B 表列 因为在那个方向上关系是很清楚的。但是,从 表列 向上更复杂,因为您不知道要层叠到哪个表。在中定义两个字段 表列 一个引用其他表,然后您可以定义所有三个表之间的关系,知道对于任何给定的记录,只涉及一个或两个表,而不涉及所有三个表。或者,您可以使用代码来确定将这个特定行关联到哪个表,并相应地进行级联。

        3
  •  0
  •   Gambrinus    15 年前

    我不知道你用的是哪种数据库管理系统,但我不知道有哪种系统可以接受多个家长。您可以在表3上定义一个索引(只是为了更快),并在应用程序中实现级联删除。