我正在开发一个python程序,它允许用户通过在文件上附加“标签”来对文件进行分类。这些标签可以以彼此的分层关系存在。例如,“猫”标签可以被归类为“哺乳动物”标签的“后代”。因此,一旦文件被标记为“狗”,也可以通过“哺乳动物”标记来访问它。
这些标记及其相互之间的关系以及它们与文件之间的关系显然需要存储在数据库中,而我最熟悉的是关系数据库。
我非常喜欢在关系数据库中存储树的Modified Pre-order Tree Traversal方法,因为它消除了递归的需要,并且需要更少的数据库查询。
但是,我也希望简化具有多个父级的标签。例如,“狗”可以是“哺乳动物”和“四条腿的东西”的孩子,其中并不是所有的四条腿的东西都是哺乳动物甚至是动物(例如桌子),并且“哺乳动物”和“四条腿的东西”标签没有“共同的祖先”。
有没有人知道一种方法,可以在数据库中表示这种关系,同时保持MPTT方法的一些优点?
谢谢你的帮助。
发布于 2012-07-20 05:32:47
您所描述的是一个非循环有向图,而不是树,因此您不能使用任何sql“树存储”方法,如MPTT。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 B
A C
A D
C D注意,我添加了(A, D)。
https://stackoverflow.com/questions/11569152
复制相似问题