【问题标题】:Database table design for ordered tree list有序树列表的数据库表设计
【发布时间】:2016-11-29 17:00:41
【问题描述】:

我需要创建代表如下树结构的 MySQL 表:

Root
|- Chapter 1
|     |- Chapter 1.1
|     |    |- Article 1.1.1
|     |    |- Article 1.1.2
|     |- Article 1.2
|     |- Chapter 1.3
|          |- Chapter 1.3.1
|          |      |- Article 1.3.1.1
|          |      |- Article 1.3.1.2
|          |- Article 1.3.2
|          |- Article 1.3.3
|- Chapter 2
      |-Chapter 2.1
      |     |- ...
      |- Chapter 2.2
      |- ...

简单来说,有两种类型的实体:章节和文章。文章是其下没有子实体的最小实体,而章节可以包含子章或文章作为子实体。每个实体都有一个 ID 和一个名称。

孩子的顺序没有固定规则,可以是章节,然后是文章,然后是章节。

另一个挑战是,当一个章节从一个章节重新定位到另一个章节时,所有的孩子也应该相应地重新定位。比如我把1.3.1章移到1.1章下(所以1.3.1章变成1.1.3章),那么1.3.1.1和1.3.1.2条也要移动,变成1.1.3.1和1条1.1.3.2。同时第1.3.2条和第1.3.3条将分别成为第1.3.1条和第1.3.2条。

所以我要问的是,如何设计数据库表以呈现这些关系?以及添加新元素/删除元素和重新定位元素的 SQL 会是什么样子? (我可以使用 Ajax 来处理重新定位交互,并使用 PHP 来生成那些层次编号)

另外,由于树通常很长,我希望避免仅仅因为只有一个元素被重新定位而更新所有元素。 (不确定这个愿望在技术上是否可行。)

【问题讨论】:

    标签: database tree


    【解决方案1】:

    我找到的关于在数据库中表示树结构的最佳信息是Joe Celko's Trees and Hierarchies in SQL for Smarties

    你可能可以在网上找到足够的信息,但我建议你买这本书,我发现它在实现嵌套集层次结构时非常有用。

    您可以使用邻接列表或嵌套集来对数据库中的树进行建模,我假设您使用的是邻接列表(其中每个条目都有一个 parent 属性)

    如果您希望能够将整个子树从一个父级移动到花药,那么它应该像更改 parent_id(或您使用的任何 PK)以引用新父级一样简单。嵌套集模型需要在移动子树时更改所有节点。

    但是,嵌套集上的其他操作更容易,例如选择特定父节点下的所有子节点。这对于邻接列表模型可能会更加困难,但随着递归 CTE 的出现变得更加容易。

    如果您不担心内容的顺序,我会避免将章节编号与您的数据一起存储。当您选择数据时应用它们,然后您就不必在树更改时更新每个节点。

    【讨论】:

    • 感谢您的图书推荐。可悲的是,我迫不及待地想用这本书来解决我的问题。我会尝试用谷歌搜索你建议的技术。是的,章节编号将由 PHP 生成,而不是存储在数据库中
    猜你喜欢
    • 2020-01-13
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多