database - Django:我如何建模異構數據類型的樹?




database-design django-models (3)

我需要在我的數據庫中存儲一個樹數據結構,為此我計劃使用django-treebeard或者django-mptt 。 我的困惑之處在於,每個節點可能是三種不同的可能類型之一:根節點將始終是一個類型A實體,葉節點是一個類型C實體,而其間的任何東西都將是類型B實體。 我想知道模擬這種情況的最好方法。

更新:我第一次嘗試模型繼承,我認為這可能是最好的方法。 不幸的是,django-treebeard的公共API並不是真的被設計來處理這個問題。 我最終得到它與GenericForeignKey工作。 非常感謝你的答案。


你的三種類型可能最容易處理為FK與基本樹的關聯。

樹可以是同類 - 類MyNodetreebeard.Node的直接子類。 你的節點可以有一個標誌(Root,Middle,Leaf)和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)

如果樹結構是應用程序的一個組成部分,請考慮使用除關係數據庫以外的其他東西。 也許neo4j?





django-treebeard