2010-08-02 136 views
3

最佳做法,我会尽力揭露尽可能明确;)DB设计:分层结构

嗯,我需要存储一些数据可以linket以自己为父母>孩子的关系,没有 - 极限深度。

我的第一个尝试是:

entry_id | parent_id | value 
    1 | NULL | Foo //foo is the grand parent 
    2 | 1  | Bar //bar is child of Foo 
    3 | 1  | Baz //baz too 
    4 | 2  | Bho //bho is child of Bar 
    5 | 4  | Som //som is child of Bho 
    6 | NULL | Git //another grand parent 
    7 | 6  | Tim //Git's child 

..和等。

这个结构的工作原理,但它是不可能的(或至少,我不能通过)找到所有的Foo孩子和'子孩子'只有一个查询..这需要一个循环。

我的目标是有一个结构SELECT查询优化,可以给我一个镜头的所有关系,是这样的:

SELECT "ALL SONS OF Bar" 

输出:

entry_id | parent_id | value 
    1  | NULL | Bar 
    4  | 2  | Bho 
    5  | 4  | Som 

但这种结构犯规似乎让我这样做。

有什么想法?

如果能够决定的事情,我会在PostgreSQL上运行(我想用数组字段类型,但查询不会有太大的快)

编辑为菲利普评论:在我的具体的数据不应该更改太频繁,但我可能需要将此结构用于其他类似的任务 - 但不是相同的 - 数据可以更新很多次。

作为一个侧面说明,使用外键(或类似的行为)将是最好的(删除一个“父亲”应该删除所有孩子的 - 无孤儿被允许)

+0

数据多久会发生变化,以及它将如何变化(添加叶子,交换分支,从中间删除节点/处理孤儿等等)。更简单的系统可以允许快捷方式,但如果您需要严格的灵活性,事情会变得棘手。 – 2010-08-02 18:25:10

+1

值0是错误的,没有这个值的entry_id:任何外键约束都会失败。没有父母时使用NULL。 – 2010-08-02 19:15:34

+0

@frank:你说得对。 – Strae 2010-08-02 21:02:11

回答

10

我认为你会从阅读中受益Managing Hierarchical Data in MySQL。它讲述了如何将一张桌子变成一个只有几个属性和一些家务的层次结构。即使你不打算这样做,这是有见地的。

对于PostgreSQL,您可以使用WITH RECURSIVE查询:WITH Queries (Common Table Expressions)
您至少需要8.4版才能使用它们。

+1

+1 WITH RECURSIVE功能。 – rfusca 2010-08-02 17:57:43

4

比尔Karwin取得了约分层数据一个不错的幻灯片:

http://www.slideshare.net/billkarwin/models-for-hierarchical-data

正如JMZ已经说过,递归查询是一个真正的问题解决者。

+1

如果您观看幻灯片,请特别注意嵌套集模型。另请注意,邻接表是您的设计。 – 2010-08-03 12:09:19