在关系数据库设计中,应该担心一个(或多个)"循环图"冒充问题?
(简化)例如,表格
T1( T1_Id ,...)
T2( T2_Id ,T1_Id_Fk,......)
T3( T1_Id_Fk,T2_Id_Fk ,..)
主键是粗体。
T1中的行有双重作用。 T1行r1可以与T2中的行r2处于关系T3,但是它也可以是(可能是相同的)行r2的父行。在T2。这两种关系是正交的。
我想出了类似的东西:
T1_Base( T1_Id ,...)
T1_Child1( T1_C1_Id ,...)
T1_Child2( T1_C2_Id ,...)
T2( T2_Id ,T1_C1_Id_Fk,...)
T3( T1_C2_Id_Fk,T2_Id_Fk ,...)
我们在T1_Base和T1_Child1和T1_Child2之间分别有一对一的关系,以消除这里描述的一些可能的级联问题Relational database design cycle,但我仍然有一个循环。
我是否应该在每个FK都使用ON CASCADE NO ACTION定义的环境中担心这个问题?
答案 0 :(得分:1)
FK(外键)约束定向。 FK声明是一个声明,用于表格和表格的值。列列表显示为某些其他“引用”表格的子行值。列列表。当人们谈论FK“循环”时,他们的意思是FK参考的循环都是从头到尾。
这里似乎没有任何此类周期。
( Tables 表示应用程序关系/关联.FK约束通常称为“关系”,尽管它们实际上只是关于在每个数据库状态中都为true的表的语句。虽然每个FK都有一个关联的查询 - 代表关联关系/关联的可表达的表。)
这种周期没有逻辑问题。当发生这种情况时,这些表对于那些超级键/ UNIQUE列列表具有完全相同的子行值集。 (实际上每对表之间存在双向约束。)在所有FK列列表相同(相同名称,相同顺序)且所有非FK列不同的简单情况下,这意味着不是您可以使用单独的表,只使用一个表作为它们的连接。否则,在适当的列重命名后,您仍然可以只使用一个表。
但是许多DBMS无法处理被声明的FK参考周期,因为FK声明对更新中的级联执行双重任务,并且DBMS设计人员没有为设计人员提供设施来说明什么时候级联应该发生在什么时候一个循环。因此,如果您不想要单表设计,那么您将通过删除其中一个声明性FK约束来强制删除循环。虽然您可以通过触发器强制执行约束,这是SQL DBMS中唯一可用的常规约束工具。
PS由于您的第一个设计可能有T3 (T1_Id_Fk, T2_Id_Fk) references T2 (T1_Id_Fk, T2_Id)
和T2 (T1_Id_Fk) references T1(T1_Id)
,因此您的第二个设计可能没有正确约束。