在考虑数据库规范化规则时,首选哪种表设计:
请考虑以下描述有序树的节点表的设计。密钥是一个复合密钥。
- ck:组合键
- 父节点:父节点
- 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列。第二种设计增加了一个替代键,并且有7列。第三种设计有5列,它使用代理来保存一列。
是否有任何规范化规则(或其他数据库设计规则)更喜欢一种设计而不是其他设计?
更新
可选设计:子类型节点表、isParent标志、嵌套集。这些设计具有更大的读/写复杂性。
设计4:
此设计将表格拆分为3个表格。父表和下一个表包含节点表中键的互斥子集。它为每个节点使用
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标志来指示下一个项是父项。它使用
4+1=5
列,而1列只是一位。其空间小于设计中使用的5列3)node(ck_x, ck_y, next_ck_x, next_ck_y, isParent)
设计6:
此设计使用嵌套集来创建有序树。组合键不再用于定义父项或子项的顺序。它使用
2+2=4
列。但下限柱和上限柱都应该使用sizeof(ck_x)+sizeof(ck_y)
,这等于设计1中使用的6个柱的空间。node(ck_x, ck_y, lowerBound, upperBound)
更新
设计7:
这将使用一个索引来表示节点的位置。
node(ck_x, ck_y, parent_ck_x, parent_ck_y, index)
票据
与插入和更新相比,使用上一个节点i.s.o.,下一个节点减少了对单个插入的创建和添加。
规范化与列或表的数量无关。
TL;DR根据您给我们的猜测:从可能的功能依赖性(决定候选密钥)到您如何表示树,所有这些设计都在5NF中。由于规范化的原因,这里的设计不需要更改。
规范化用其他表替换表,而不引入新列。BCNF的规范化需要知道所有的功能依赖关系;除此之外的规范化还需要了解联接依赖关系。这需要通过表格了解一行对情况的描述,以及可能出现的情况。(如果我们知道某些列是唯一的,那么我们就知道它们在功能上决定了所有列。)
首先选择可以描述可能出现的任何情况的设计,以及可以表达对这些情况的查询的设计。规范化可能会改善设计(在减少更新异常或某些冗余方面),但设计的适当性或质量的其他方面与规范化无关。必须谨慎选择树状结构的关系设计,以适应预期用途和DBMS特性。
PS 1规范化不会引入代理。功能相关性很重要;你没有给他们。候选密钥很重要;你没有给他们。(主键之所以重要,是因为它们是候选键。)阅读规范化的基本概念和步骤。
PS 2对共享同一父级的链表同级的约束不通过规范化来解决。仅仅因为存在重复的值,就不必存在冗余;冗余是指由行在表中或不在表中产生的重复语句。关于"冗余"。事实上,描述树的明显的基本关系方式只是一个表"父P有子C"或"父P第N个子C"。您是在相对地表示树。不要用关系表示树的(非关系)表示。
PS 3您对列的数量和大小/空间(包括代理密钥的使用)的担忧几乎肯定是误导了。只要根据您的查询和更新进行最直接的设计即可。(同样,你还没有描述。)