具有复合键的有序树的表设计

时间:2016-01-01 23:47:59

标签: database database-normalization composite-key surrogate-key

在考虑数据库规范化规则时,首选哪种表格设计:

对于描述有序树的节点表,请考虑以下设计。密钥是复合密钥。

  • ck:复合键
  • 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键,并有7个columsn。第三种设计有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列只有一点。这比设计3)中使用的空间少于5列

    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.与插入和更新相比,下一个节点减少了对单个插入的创建和添加。

  • 规范化与列或表的数量无关。

1 个答案:

答案 0 :(得分:1)

TL; DR 根据您提供的内容进行猜测:从可能的功能依赖关系(确定候选关键字)到您表示树的方式,所有这些设计均为5NF。由于规范化的原因,这里不需要改变设计。

规范化将其他表替换为表而不引入新列。归一化到BCNF需要知道所有功能依赖性;除此之外的规范化需要了解连接依赖性。这需要通过在表格中知道行的状态以及可能出现的情况。 (如果我们知道某些列是唯一的,那么我们知道它们在功能上确定所有列。)

首先选择设计,您可以通过这些设计描述可能出现的任何情况,并通过该设计表达对这些情况的查询。然后,规范化可以改进设计(在减少更新异常或某些冗余方面),但是设计的适当性或质量的其他方面与规范化无关。必须谨慎选择树形结构关系设计,以适应预期用途和DBMS特性。

PS 1 规范化不会引入代理人。功能依赖性很重要;你没有给他们。候选人密钥很重要;你没有给他们。 (主键只是因为它们是候选键。)阅读标准化的基本概念和步骤。

PS 2 标准化无法解决对共享同一父级的链接列表兄弟的约束。仅仅因为有重复的,就不需要冗余;冗余是指在表中或不在表中的重复语句Re "redundancy".事实上,描述树的明显基本关系方式只是一个表格,父母P有一个孩子C"或者"父母P有第N个孩子C"。您是关系代表。不要在关系上表示树的(非关系)表示

PS 3 您对列的数量和大小/空间的关注(包括使用代理键)几乎肯定是错误的。只需根据您的查询和更新进行最直接的设计。 (再说一遍,你还没有描述过。)