如何在数据库模式中表达这个约束?

joh*_*nes 7 constraint relational-theory

我在 BCNF 中有以下功能依赖项:

a,b -> c
a -> d
b -> d
Run Code Online (Sandbox Code Playgroud)

有了附加约束, noab应该与 a c、 whereabhave 不同的ds 组合。

例子:

a | d   b | d   a | b | c
-----   -----   ---------
1 | 3   5 | 3   1 | 5 | 6
2 | 4           2 | 5 | 7
Run Code Online (Sandbox Code Playgroud)

第一行a,b,c是允许的 ( 1->3, 5->3),但第二行是禁止的,因为 ( 2->4, 5->3) 4 != 3

这个额外的约束对我的数据有两个影响。对于每个a,b,c,有两种冗余的方法来确定d。可能存在违反约束的数据。我的架构如何反映这个额外的约束?

one*_*hen 3

简而言之,创建一个ASSERTION以确保任何时候都不会违反业务规则,例如完整标准 SQL-92 语法:

CREATE TABLE T1
(
 a INTEGER NOT NULL, 
 d INTEGER NOT NULL, 
 UNIQUE (a, d)
);

CREATE TABLE T2
(
 b INTEGER NOT NULL, 
 d INTEGER NOT NULL, 
 UNIQUE (b, d)
);

CREATE TABLE T3
(
 a INTEGER NOT NULL,
 b INTEGER NOT NULL, 
 c INTEGER NOT NULL, 
 UNIQUE (a, b, c)
);

CREATE ASSERTION no_a_and_b_should_be_combined_with_a_c_where_a_and_b_have_different_ds
   CHECK (
          NOT EXISTS (
                      SELECT *
                        FROM T3
                       WHERE NOT EXISTS (
                                         SELECT T1.d
                                           FROM T1
                                          WHERE T1.a = T3.a 
                                         INTERSECT        
                                         SELECT T2.d
                                           FROM T2
                                          WHERE T3.b = T3.b 
                                        )
                     )
         );
Run Code Online (Sandbox Code Playgroud)

坏消息是没有商业(或其他?)SQL 产品支持CREATE ASSERTION.

大多数工业级 SQL 产品都支持触发器:可以在每个适用的表上的触发器中实现上述内容。MS Access 是我所知道的唯一支持约束子查询的商业产品CHECK,但我不认为它具有工业强度。还有进一步的解决方法,例如强制用户仅通过存储过程更新表,这些存储过程可以证明永远不会使数据库处于非法状态。