简体   繁体   English

在关系数据库中表示与“多重继承”的层次关系

[英]Representing hierarchical relationships with “multiple inheritance” in a relational database

I'm working on a python program that allows the user to categorise files by attaching 'tags' to them. 我正在开发一个python程序,允许用户通过附加“标签”对文件进行分类。 These tags can stand in hierarchical relationships to one another. 这些标签可以彼此存在层次关系。 For example, the 'cat' tag can be categorized as a "descendant" of the 'mammal' tag. 例如,'cat'标签可以归类为'哺乳'标签的“后代”。 As a consequence, once a file is tagged as 'dog', it can be accessed via the 'mammal' tag as well. 因此,一旦文件被标记为“狗”,它也可以通过“哺乳动物”标签访问。

These tags and their relationships to each other and to files will obviously need to be stored in a database, and I'm most familiar with relational databases. 这些标签及其相互之间和文件的关系显然需要存储在数据库中,而且我最熟悉的是关系数据库。

I very much like the Modified Pre-order Tree Traversal method for storing trees in a relational database because it removes the need for recursion and requires fewer database queries. 我非常喜欢用于在关系数据库中存储树的Modified Pre-order Tree Traversal方法,因为它消除了递归的需要并且需要更少的数据库查询。

However, I also want to facilitate tags with multiple parents. 但是,我也希望为多个父母提供标签。 For example, 'dog' could be a child of 'mammal' and also of 'four-legged-thing' where not all four legged things are mammals or even animals (eg tables), and the 'mammal' and 'four-legged-thing' tags have no "common ancestor". 例如,“狗”可能是“哺乳动物”的孩子,也可能是“四足物”的孩子,其中并非所有四条腿的东西都是哺乳动物甚至动物(例如桌子),“哺乳动物”和“四足动物” -thing'标签没有“共同的祖先”。

Does anyone know of a method of representing such relationships in a database while maintaining some of the advantages of the MPTT method? 有没有人知道在数据库中表示这种关系的方法,同时保持MPTT方法的一些优点?

Thanks for any help. 谢谢你的帮助。

What you are describing is an acyclic directed graph, not a tree, so you can't use any of the sql "tree-storage" methods like MPTT. 您所描述的是非循环有向图,而不是树,因此您不能使用任何sql“树存储”方法,如MPTT。 Here is an article that demonstrates an adjacency-list approach to this problem. 这篇文章演示了这个问题的邻接列表方法。

I highly recommend that you do not go down this path, however, not because of the difficulty of implementation, but because you will end up confusing and frustrating your users. 我强烈建议你不要走这条路,不是因为实施的困难,而是因为你最终会让用户感到困惑和沮丧。 In my experience users make poor use of complex ontological systems and are easily confused by them. 根据我的经验,用户很难使用复杂的本体系统,很容易被它们搞糊涂。 Either use a flat "tag" namespace with no parent-child relationships, or use a tree arrangement with at most one parent per node. 使用没有父子关系的扁平“标记”命名空间,或者使用每个节点最多一个父级的树排列。

But if you want to have a graph, he most straightforward way is to have a table like this: 但是如果你想要一个图形,他最直接的方法就是拥有一个这样的表格:

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)
);

You will probably not be able to avoid recursive queries. 您可能无法避免递归查询。 When you want to create a matching search, use the tags you have as search criteria and recursively add child tags until you have a complete tag list. 如果要创建匹配搜索,请使用您拥有的标记作为搜索条件,并递归添加子标记,直到您拥有完整的标记列表。

You will also have to be careful about creating cycles. 您还必须小心创建周期。 When you add a relationship, you need to recursively visit parents and make sure you don't end up at the same node twice. 添加关系时,需要递归访问父项,并确保不会在同一节点上两次结束。

Something you can do to avoid recursive queries and help detect cycles is to denormalize your data a bit by making all relationships explicit for every node. 为避免递归查询和帮助检测周期,您可以采取的措施是通过使每个节点显式显示所有关系来对数据进行非规范化。 What I mean is, suppose A is a child of B and C, and C is a child of D. 我的意思是,假设A是B和C的孩子,C是D的孩子。

Instead of the minimum number of edges necessary to represent this fact: 而不是表示这个事实所需的最小边数:

tag_child_id  tag_parent_id
A             B
A             C
C             D

You would make all implicit relationships (ones you would have had to find via recursion) explicit: 您可以使所有隐式关系(您必须通过递归找到的关系)显式:

A             B
A             C
A             D
C             D

Notice that I added (A, D) . 请注意,我添加了(A, D)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM