Relational database design - “cyclic” graphs

2019-02-16 01:25发布

In relational database design, should one worry about one (or more) "cyclic graphs" posing problems?

(Simplified) E.g., tables

T1(T1_Id, ...)
T2(T2_Id, T1_Id_Fk, ...)
T3(T1_Id_Fk, T2_Id_Fk, ..)

Primary keys are bolded.

Rows in T1 have a double role. A T1 row r1 can be in relationship T3 with a row r2 in T2, but it can also be a parent row for a (possibly the same) row r2' in T2. These two relationships are orthogonal.

I came up with something like this:

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, ...)

where we have one-to-one relationships between T1_Base and T1_Child1 and T1_Child2, respectively, to eliminate some of the possible cascading issues described here Relational database design cycle, but I still get a cycle.

Should I even be worried about this in a context where every FK is defined with ON CASCADE NO ACTION?

1条回答
霸刀☆藐视天下
2楼-- · 2019-02-16 02:02

A FK (foreign key) constraint is directed. A FK declaration is a statement that subrow values for a table & column list appear as subrow values for some other "referenced" table & column list. When people talk about FK "cycles" they mean cycles of FK references all put head to tail.

You don't appear to have any such cycles here.

(Tables represent application relationships/associations. FK constraints are often called "relationships" although they are actually just statements about tables that are true in every database state. Although every FK has an associated query-expressible table representing an associated relationship/association.)

There's no logical problem with such cycles. When that happens, the tables all have exactly the same set of subrow values for those superkey/UNIQUE column lists. (Indeed there is a 2-way constraint between every pair of tables.) In the simple case where all the FK columns lists are the same (same names, same order) and all non-FK columns are different, it means that instead of the separate tables you could use just the one table that is their join. Otherwise, after suitable column renamings you could still use just one table.

But many DBMSs can't handle FK reference cycles being declared, because FK declarations do double duty for cascades on update, and the DBMS designers haven't offered a facility for the designer to say what order cascades should happen in when there's a cycle. So if you don't want a one-table design then you are forced drop the cycle by dropping one of the declarative FK constraints. Although you can enforce the constraint via a trigger, which is the only general constraint facility available in SQL DBMSs.

PS Since your first design probably has T3 (T1_Id_Fk, T2_Id_Fk) references T2 (T1_Id_Fk, T2_Id) and T2 (T1_Id_Fk) references T1(T1_Id), your 2nd design is probably not properly constraining.

查看更多
登录 后发表回答