joh*_*nes 7 constraint relational-theory
我在 BCNF 中有以下功能依赖项:
a,b -> c
a -> d
b -> d
Run Code Online (Sandbox Code Playgroud)
有了附加约束, noa
和b
应该与 a c
、 wherea
和b
have 不同的d
s 组合。
例子:
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
。可能存在违反约束的数据。我的架构如何反映这个额外的约束?
简而言之,创建一个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
,但我不认为它具有工业强度。还有进一步的解决方法,例如强制用户仅通过存储过程更新表,这些存储过程可以证明永远不会使数据库处于非法状态。