实现图树的最佳数据库结构[重复]

Posted

技术标签:

【中文标题】实现图树的最佳数据库结构[重复]【英文标题】:Best database structure to implement a graph tree [duplicate] 【发布时间】:2016-11-28 07:00:50 【问题描述】:

我正在尝试设计一个具有金字塔关系的数据库。例如这是我的数据:

那么,我怎样才能既存储这些数字又保持它们的关系呢?


目前我是这样做的:

// myTree
+----+------+--------+
| id | node | parent |
+----+------+--------+
| 1  | 8    | Null   |
| 2  | 10   | 8      |
| 3  | 3    | 8      |
| 4  | 14   | 10     |
| 5  | 6    | 3      |
| 7  | 1    | 3      |
| 8  | 13   | 14     |
| 9  | 7    | 6      |
| 10 | 4    | 6      |
+----+------+--------+

但在这种情况下,我只能通过一次查询选择一级图表。虽然我需要为节点选择整个分支。敌人的例子:

$node = 14;

预期结果:

[8, 10, 14, 13]

注意:节点是唯一的。

无论如何,如何设计数据库以使其通过一个查询访问所有级别?

【问题讨论】:

点击Managing Hierarchical Data in mysql mikehillyer.com/articles/managing-hierarchical-data-in-mysql的链接 这是一个常见问题解答。请用谷歌搜索你的标题。 升级到 MySQL 8.0 或 MariaDB 10.2,以便您可以使用递归 CTE。 【参考方案1】:

您可能想查看nested sets。在实际尝试在工作系统上之前,我很早就知道这项技术,主要是因为很少有关于它的正面报道。使用邻接表或任何其他方法可以轻松查询极其复杂的图形信息,这让我感到惊喜。

但是,它有一些缺点,使其在非常特定的环境中很有用:列表必须是静态的。也就是说,一旦创建,列表本身几乎不需要维护——节点之间的相对移动、添加新节点或删除现有节点。这是因为每一行都依赖于其他行(这些行依赖于其他行,依此类推)。列表中的更改可能涉及更新列表中跟随它的所有条目。这是一个很小的变化。

我有一个完美的用例:所有州、哥伦比亚特区和美国领土的教育标准。教育标准每年最多更改一次,而大多数州的更改频率要低得多。无论如何,一旦学年开始,当时有效的标准在整个学年期间仍然有效。因此,一旦列表在年初建立,它们直到明年年初才会改变。

想象一下能够查询仅包含在树的任何节点的子树中的信息。绝对的powah!

还有其他一些我从未实施过的好用途,例如学校目录,一旦学期开始,这些目录也会发生很小的变化。

请注意,“更改”指的是操纵树结构的更改:插入新节点、将节点从一个地方移动到另一个地方、删除一个节点等。对节点内容的更新是不是问题。

另外请注意,我有几个星期的时间来熟悉这个结构。您可以编写一些激进的查询,但需要一段时间才能熟悉系统。

它现在可能不适合您的需求,但对它何时变得有用有一个基本的了解并没有什么坏处。它的结构太强大了,不容忽视。

【讨论】:

【参考方案2】:

如果您必须在 MySQL 中执行此操作,@philipxy 为您提供了一个很好的链接,但您应该知道 MySQL 对于分层/树数据来说是一个糟糕的选择。 其他 DBMS,例如 Oracle、SQL Server 和 PostgreSQL,对于邻接表方法来说要好一些,因为它们至少支持迭代(“递归”)查询。 为了合身,我建议你看看neo4j

【讨论】:

我很高兴你本着我的意思接受了我的评论 :)【参考方案3】:

您的数据库设计是正确的,唯一的挑战是如何从单个查询中获取所有子节点。为此,您可以编写用户定义的函数并从查询中调用该函数。内部函数可以编写分层查询或数据库特定代码,没有太大区别,因为此函数将仅从查询中调用。

【讨论】:

以上是关于实现图树的最佳数据库结构[重复]的主要内容,如果未能解决你的问题,请参考以下文章

王道数据结构与算法树(八——1)

键值对数据结构的最佳实现?

JavaScript数据结构与算法 - 树

处理规则层次结构/树的最佳方法

存储键值对的最佳 Java 数据结构 [重复]

动手生成 Delphi xe DBTreeview 三级行政图树 省市县