Table 设计具有复合键的有序树
Table design for an ordered tree with composite keys
考虑数据库规范化规则时,首选table设计:
考虑以下描述有序树的节点 table 的设计。该键是复合键。
- ck:复合键
- parent: parent 节点
- next:下一个节点,其中
next.parent = parent.
(这定义了一个正向链表)
- sk:代理键
设计 1:
node(ck_x, ck_y, parent_ck_x, parent_ck_y, next_ck_x, next_ck_y)
设计 2:
node(sk, ck_x, ck_y, parent_ck_x, parent_ck_y, next_ck_x, next_ck_y)
设计 3:
node(sk, ck_x, ck_y, parent_sk, next_sk)
第一个设计有 6 列。第二个设计添加了一个 surragete key 并且有 7 列。第三个设计有 5 个列,它使用代理项来保存一个列。
是否有任何规范化规则(或其他数据库设计规则)偏向于一种设计?
更新
替代设计:子类型节点 table、isParent 标志、嵌套集。这些设计具有更大的 read/write 复杂性。
设计 4:
此设计将 table 拆分为 3 个 table。 parent 和下一个 table 包含来自节点 table 的键的互斥子集。它为每个节点使用 2+4=6
列。
node(ck_x, ck_y)
parent(ck_x, ck_y, parent_ck_x, parent_ck_y)
next(ck_x, ck_y, next_ck_x, next_ck_y)
设计 5:
此设计使用 isParent 标志来指示下一项是 parent。它使用 4+1=5
列,1 列只是一点点。比设计 3)
中使用的 5 列少 space
node(ck_x, ck_y, next_ck_x, next_ck_y, isParent)
设计 6:
此设计使用嵌套集来创建有序树。复合键不再用于定义 parent 或 children 的顺序。它使用 2+2=4
列。但是下限和上限列应该都使用 sizeof(ck_x)+sizeof(ck_y)
,这等于设计 1 中使用的 6 列的 space。
node(ck_x, ck_y, lowerBound, upperBound)
更新
设计 7:
这使用节点位置的索引。
node(ck_x, ck_y, parent_ck_x, parent_ck_y, index)
备注
使用前一个节点i.s.o。与插入和更新相比,下一个节点减少了对单个插入的创建和添加。
规范化与列数或 tables 无关。
TL;DR 根据您给我们的内容进行猜测:从可能的功能依赖性(确定候选键)以及您如何表示树,所有这些设计在 5NF 中。由于规范化的原因,此处无需更改设计。
规范化将 table 替换为其他 table 而不引入新列。规范化为 BCNF 需要知道所有的函数依赖;除此之外的规范化需要了解连接依赖性。这需要通过 table 了解一行对情况的说明,以及可能出现的情况。 (如果我们知道某些列是唯一的,那么我们就知道它们在功能上决定了所有列。)
首先选择可以描述可能出现的任何情况并可以表达对这些情况的疑问的设计。然后规范化可能会改进设计(在减少更新异常或某些冗余方面),但设计的适当性或质量的其他方面与规范化无关。 Tree-structured 必须谨慎选择关系设计以适应预期用途和 DBMS 特征。
PS 1 规范化不引入代理项。功能依赖很重要;你还没有给他们。候选键很重要;你还没有给他们。 (主键仅在它们是候选键时才重要。)阅读规范化的基本概念和步骤。
PS 2 linked-list 兄弟姐妹同父异母的约束没有通过规范化解决。仅仅因为有重复的 值 就不需要冗余;冗余是关于 行 是否在 table 中重复的 语句 。 事实上,描述树的最明显的基本关系方式就是 table "parent P has child C" 或 "parent P has Nth child C"。您在关系上代表一棵 树 。不要关系地表示树的 (non-relational) 表示。
PS 3 您对列数和 size/space 的关注(包括代理键的使用)几乎肯定是错误的。只需根据您的查询和更新做出最直接的设计。 (同样,你没有描述。)
考虑数据库规范化规则时,首选table设计:
考虑以下描述有序树的节点 table 的设计。该键是复合键。
- ck:复合键
- parent: parent 节点
- next:下一个节点,其中
next.parent = parent.
(这定义了一个正向链表) - sk:代理键
设计 1:
node(ck_x, ck_y, parent_ck_x, parent_ck_y, next_ck_x, next_ck_y)
设计 2:
node(sk, ck_x, ck_y, parent_ck_x, parent_ck_y, next_ck_x, next_ck_y)
设计 3:
node(sk, ck_x, ck_y, parent_sk, next_sk)
第一个设计有 6 列。第二个设计添加了一个 surragete key 并且有 7 列。第三个设计有 5 个列,它使用代理项来保存一个列。
是否有任何规范化规则(或其他数据库设计规则)偏向于一种设计?
更新
替代设计:子类型节点 table、isParent 标志、嵌套集。这些设计具有更大的 read/write 复杂性。
设计 4:
此设计将 table 拆分为 3 个 table。 parent 和下一个 table 包含来自节点 table 的键的互斥子集。它为每个节点使用
2+4=6
列。node(ck_x, ck_y)
parent(ck_x, ck_y, parent_ck_x, parent_ck_y)
next(ck_x, ck_y, next_ck_x, next_ck_y)
设计 5:
此设计使用 isParent 标志来指示下一项是 parent。它使用
中使用的 5 列少 space4+1=5
列,1 列只是一点点。比设计 3)node(ck_x, ck_y, next_ck_x, next_ck_y, isParent)
设计 6:
此设计使用嵌套集来创建有序树。复合键不再用于定义 parent 或 children 的顺序。它使用
2+2=4
列。但是下限和上限列应该都使用sizeof(ck_x)+sizeof(ck_y)
,这等于设计 1 中使用的 6 列的 space。node(ck_x, ck_y, lowerBound, upperBound)
更新
设计 7:
这使用节点位置的索引。
node(ck_x, ck_y, parent_ck_x, parent_ck_y, index)
备注
使用前一个节点i.s.o。与插入和更新相比,下一个节点减少了对单个插入的创建和添加。
规范化与列数或 tables 无关。
TL;DR 根据您给我们的内容进行猜测:从可能的功能依赖性(确定候选键)以及您如何表示树,所有这些设计在 5NF 中。由于规范化的原因,此处无需更改设计。
规范化将 table 替换为其他 table 而不引入新列。规范化为 BCNF 需要知道所有的函数依赖;除此之外的规范化需要了解连接依赖性。这需要通过 table 了解一行对情况的说明,以及可能出现的情况。 (如果我们知道某些列是唯一的,那么我们就知道它们在功能上决定了所有列。)
首先选择可以描述可能出现的任何情况并可以表达对这些情况的疑问的设计。然后规范化可能会改进设计(在减少更新异常或某些冗余方面),但设计的适当性或质量的其他方面与规范化无关。 Tree-structured 必须谨慎选择关系设计以适应预期用途和 DBMS 特征。
PS 1 规范化不引入代理项。功能依赖很重要;你还没有给他们。候选键很重要;你还没有给他们。 (主键仅在它们是候选键时才重要。)阅读规范化的基本概念和步骤。
PS 2 linked-list 兄弟姐妹同父异母的约束没有通过规范化解决。仅仅因为有重复的 值 就不需要冗余;冗余是关于 行 是否在 table 中重复的 语句 。
PS 3 您对列数和 size/space 的关注(包括代理键的使用)几乎肯定是错误的。只需根据您的查询和更新做出最直接的设计。 (同样,你没有描述。)