gro*_*tar 6 normalization foreign-key database-theory
假设有实体称为singulars,实体称为relationships。
singulars组成一个relationships实体正好需要两个。
那对单数不能relationships以任何顺序在中的其他地方重复。
建模它的一种方法可能是这样的:
+----------------+
|relationships | +----------+
+----------------+ |singulars |
|id | +----------+
|singular_id_1 <---------+id |
|singular_id_2 <---+ |attribute1|
|pair_description| |attribute2|
|pair_date | | |
| | +----------+
+----------------+
Run Code Online (Sandbox Code Playgroud)
使用这种模式,有必要检查两个外键字段relationships是否存在singulars,它可能在任一侧。顺序无关紧要,但它是在模式中定义的......所以查询最终会得到许多AND/OR组和案例。
扩展这种方法可以为每对存储两条记录,并在singular_id_[n]两侧交换。虽然这解决了一些查询的复杂性,但它会引入额外的复杂性使其不可行。
使用中间表似乎是一种潜在的解决方案:
+----------------+ +-----------------------+
|relationships | |singulars_relationships| +----------+
+----------------+ +-----------------------+ |singulars |
|id <-------+relationship_id | +----------+
|pair_description| |singular_id +-------->id |
|pair_date | | | |attribute1|
| | +-----------------------+ |attribute2|
+----------------+ | |
+----------+
Run Code Online (Sandbox Code Playgroud)
所以记录可能会变成这样:
+----------------------------------+
|relationships |
+----------------------------------+
|id pair_description pair_date |
+----------------------------------+
|1 Fizz buzz blitz 2022-02-20|
|2 Blitz buzz fizz 2022-02-22|
+----------------------------------+
+----------------------------------+
|singulars_relationships |
+----------------------------------+
|relationship_id singular_id |
+----------------------------------+
|1 1 |
|1 2 |
|2 3 |
|2 4 |
+----------------------------------+
+-----------------------------+
|singulars |
+-----------------------------+
|id attribute1 attribute2 |
+-----------------------------+
|1 Fizz Blitz |
|2 Buzz Foo |
|3 Bar World |
|4 Blorg Hello |
+-----------------------------+
Run Code Online (Sandbox Code Playgroud)
在那里,singulars_relationships是定义对的地方。如果 asingular_id存在于那里,则它已经是一对。这种模式可能出现的一个问题可能是三个或更多singular_ids 最终可能与 a 相关联relationship_id,然后“恰好 n”约束将受到损害。
这种情况有官方条款吗?以及其他理论和替代方案?
这种情况有官方条款吗?
是的。这是一个对称关系。这里的“关系”与“关系数据库”中的含义相同。RDBMS 是一种围绕存储关系而设计的数据库管理系统。然而,RDBMS 没有存储对称关系的本机方式。您要么必须将两个元组,例如 (a,b) 和 (b,a) 存储为单独的行,要么必须使用某种约定来仅存储一个元组。一种常见的方法是对 FK 使用检查约束。
例如
check (singular_id_1 < singular_id_2)
Run Code Online (Sandbox Code Playgroud)
假设关系是反自反的。
渴望发表评论,所以我将其添加为大卫解决方案的补充。尽管该问题具有理论性质,但看看如何在现实生活中实施可能会很有趣。
在某些情况下,反自反属性和对称属性太强了,但我们仍然希望“唯一性”属性保持不变。一种常见的模式是使用BEFORE TRIGGERS使关系对称而不让用户知道对称属性:
CREATE TRIGGER trigger1
BEFORE INSERT ON t
REFERENCING NEW AS N
FOR EACH ROW
SET (N.a, N.b) = (LEAST(N.a, N.b), GREATEST(N.a, N.b));
Run Code Online (Sandbox Code Playgroud)
表中的属性:
CHECK(a<=b);
UNIQUE(a,b);
Run Code Online (Sandbox Code Playgroud)
这个主题的一个变体是使用生成的列
CREATE TABLE t
( a int not null
, b int not null
, least_a_b generated always as ( least(a,b) )
, greatest_a_b generated always as ( greatest(a,b))
, unique (least_a_b, greatest_a_b)
);
Run Code Online (Sandbox Code Playgroud)
生成的列也可能被隐藏:
least_a_b generated always as ( least(a,b) ) IMPLICITLY HIDDEN
Run Code Online (Sandbox Code Playgroud)
示例来自 Db2,但其他供应商应该存在类似的功能。
| 归档时间: |
|
| 查看次数: |
282 次 |
| 最近记录: |