实现图树的最佳数据库结构[重复]
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】:您的数据库设计是正确的,唯一的挑战是如何从单个查询中获取所有子节点。为此,您可以编写用户定义的函数并从查询中调用该函数。内部函数可以编写分层查询或数据库特定代码,没有太大区别,因为此函数将仅从查询中调用。
【讨论】:
以上是关于实现图树的最佳数据库结构[重复]的主要内容,如果未能解决你的问题,请参考以下文章