实现图树

时间:2016-11-28 07:00:50

标签: mysql sql database-design relational-database

我试图设计一个具有金字塔形关系的数据库。例如,这是我的数据:

enter image description here

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

目前我这样做:

// 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]

注意:节点是唯一的。

无论如何,我如何设计数据库以使其通过一个查询进行全面访问?

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您可能需要查看nested sets。在实际在工作系统上尝试之前,我已经了解了这种技术很长一段时间,主要是因为关于它的文章很少是积极的。使用邻接列表或任何其他方法查询极其复杂的图形信息时,我感到非常惊喜。

但是,它具有使其在特定环境中有用的缺点:列表必须是静态的。也就是说,一旦创建,列表本身的维护很少 - 节点相对于彼此的移动,添加的新节点或删除现有节点。这是因为每一行都依赖于其他行(依赖于其他行,依此类推)。列表中的更改可能涉及更新列表中其后面的所有条目。这是一项很小的改变。

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

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

我还没有其他好的用途,例如学校目录,一旦学期开始,也会经历很少的变化。

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

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

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

答案 2 :(得分:0)

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