2012-07-19 52 views
3

我正在研究一个python程序,它允许用户通过给他们附上'标签'来对文件进行分类。这些标签可以站在彼此的层次关系中。例如,'猫'标签可以被归类为'哺乳动物'标签的“后代”。因此,一旦文件被标记为“狗”,它也可以通过“哺乳动物”标签访问。用关系数据库中的“多重继承”来表示分层关系

这些标记及其相互之间和文件之间的关系显然需要存储在数据库中,而且我最熟悉关系数据库。

我非常喜欢在关系数据库中存储树的Modified Pre-order Tree Traversal方法,因为它消除了递归的需要并且需要更少的数据库查询。

但是,我也想促进多个父母的标签。例如,'狗'可能是'哺乳动物'的孩子,也可能是'四足动物'的孩子,其中并非所有的四足动物都是哺乳动物或动物(如桌子),而'哺乳动物'和'四足动物'物'标签没有“共同的祖先”。

有没有人知道在数据库中表示这种关系的方法,同时保持MPTT方法的一些优点?

感谢您的任何帮助。

回答

2

你所描述的是一个非循环有向图,而不是一棵树,所以你不能使用像MPTT这样的sql“树存储”方法。 Here is an article that demonstrates an adjacency-list approach to this problem.

然而,我强烈建议你不要走这条路,不是因为实施的困难,而是因为你最终会迷惑和沮丧你的用户。根据我的经验,用户对复杂的本体论系统的使用很少,很容易被他们所困惑。可以使用没有父子关系的扁平“标签”名称空间,也可以使用每个节点至多有一个父项的树排列。

但是,如果你想有一个图形,他最直接的方法是有一个这样的表:

CREATE TABLE tag_relationships (
    tag_child_id INTEGER NOT NULL REFERENCES tags (id) ON UPDATE CASCADE ON DELETE CASCADE, 
    tag_parent_id INTEGER NOT NULL REFERENCES tags (id) ON UPDATE CASCADE ON DELETE CASCADE, 
    PRIMARY KEY (tag_child_id, tag_parent_id) 
); 

你可能无法避免递归查询。当你想创建一个匹配的搜索时,使用你有的标签作为搜索条件并递归添加子标签,直到你有一个完整的标签列表。

您还必须小心创建周期。当你添加一个关系时,你需要递归访问父母,并确保你不会在同一个节点上结束两次。

事情可以做,以避免递归查询并帮助检测周期是通过使所有关系明确为节点进行非规范化数据位。我的意思是,假设A是B和C的孩子,C是D

的孩子

相反的边缘所必需的最小数目来表示这样一个事实:

tag_child_id tag_parent_id 
A    B 
A    C 
C    D 

你会做所有的隐含关系(那些你将不得不通过递归找到)明确:我添加(A, D)

A    B 
A    C 
A    D 
C    D 

通知。

+0

非常感谢您的回答。 – samfrances 2012-07-19 22:01:15