Database Django:如何对异构数据类型树进行建模?

Database Django:如何对异构数据类型树进行建模?,database,django,database-design,django-models,django-treebeard,Database,Django,Database Design,Django Models,Django Treebeard,我需要在我的数据库中存储一个树数据结构,我计划使用或可能使用它。我感到困惑的是,每个节点可能是三种不同类型中的一种:根节点始终是a型实体,叶节点是C型实体,而介于两者之间的任何节点都是B型实体。我想知道模拟这种情况的最佳方法 更新:我第一次尝试模型继承,我认为这可能是最好的方法。不幸的是,django treebeard的公共API并不是真正设计用来处理这个问题的。我最终让它与GenericForeignKey一起工作。非常感谢您的回答。您的三种类型可能是最容易处理的FK与基本树的关联 树可以是

我需要在我的数据库中存储一个树数据结构,我计划使用或可能使用它。我感到困惑的是,每个节点可能是三种不同类型中的一种:根节点始终是a型实体,叶节点是C型实体,而介于两者之间的任何节点都是B型实体。我想知道模拟这种情况的最佳方法


更新:我第一次尝试模型继承,我认为这可能是最好的方法。不幸的是,django treebeard的公共API并不是真正设计用来处理这个问题的。我最终让它与GenericForeignKey一起工作。非常感谢您的回答。

您的三种类型可能是最容易处理的FK与基本树的关联

树可以是同质的——类
MyNode
treebeard.Node
的直接子类。您的节点可以有一个标志(根、中间、叶)和用于a、B或C的FK。这允许您在查询MyNode实例时具有类似SQL的灵活性

这可以让你的树生长。节点可以从类型C(叶)开始,然后变形为类型B(中间)。您可以更改状态,然后更改FK的

另一种选择要复杂一点

class MyA( treebeard.Node ):
    pass

class MyB( treebeard.Node ):
    pass

class MyC( treebeard.Node ):
    pass
在这种情况下,不能“变形”节点。当节点以
MyC
开始并获取子节点时,必须删除原始
MyC
实例,并将其替换为具有新节点作为子节点的
MyB
版本。这不是不可能的,但可能会很痛苦。

如何使用从模型到它所表示的节点的内容对象的树结构

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Node(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    object = generic.GenericForeignKey('content_type', 'object_id')
在检索完整树的内容对象时,这可能会导致大量查询,但减少所需查询的数量是有必要的

# Assuming mptt, as I'm not familiar with treebeard's API

# 1 query to retrieve the tree
tree = list(Node.tree.all())

# 4 queries to retrieve and cache all ContentType, A, B and C instances, respectively
populate_content_object_caches(tree)

在某种程度上,已经为您做了很多工作,因为根、叶和其他都已经通过树API进行了固有的识别。可以在各个节点上调用is_root()和is_leaf(),以区分它们

叶和中间叶可以是同一类型的实体,并保存同一类型的数据,应用程序根据测试解释和使用数据的方式是_leaf()

根有点特别。。。他们可能希望保存与整个树相关的信息,您可能需要一种查找特定根并保存额外数据的简单方法。您可以对与根节点具有一对一关系的模型执行此操作(可能会重载save方法,并在允许保存之前检查它所指向的节点是否为_root())


总的来说,我的观点是,你可能不需要非常喜欢做你想做的事情。您所做的区分已经封装在树及其API的概念中,并且可以通过检查节点的上下文来实现与相同的基本数据不同的行为。

< P>如果树结构是应用程序的一个组成部分,考虑使用其他关系数据库。也许是neo4j