Hierarchical SQL in Django: Django-treebeard

·2022년 6월 16일
0

Hierarchical SQL

목록 보기
4/4
post-thumbnail

django-treebeard 소개

계층 구조를 표현하는 방법은 크게 네가지가 있다.

  • Adjacency List without CTE
  • Adjacency List with CTE
  • Materialized Path
  • Nested Set

앞선 Post에서 각각의 방법에 대한 Django Model, 부모/자식 노드 판별, SubTree를 구하는 예시에 대해 설명했다.
하지만, production에서 사용하기 위해서 상황마다 노드를 추가/삭제하는 방법에 대해 고민해야하고, Tree Manager class를 구현해서 사용하기 쉬운 메소드를 제공해야한다. 이는 쉬운 일이 아니고, 계층 구조를 프로젝트에 적용하기 어렵다.

django-treebeardAdjaceny List without CTE, Materialized Path, Nested Set을 쉽게 사용할 수 있도록, 각각의 Node Model과 NodeManager, TreeManager를 제공한다. wagtail이나 django-cms같은 django기반 오픈 소스들에서 계층 구조를 표현하기 위한 라이브러리로 django-treebeard를 사용하고 있다.

django-treebeard

적절한 hierarchical model 선택

  • 계층 구조를 설계하는 가장 기본은 Adjaceny List이다. 제공되는 모델 중에서 유일하게 정규화된 형태이고, 데이터의 정합성이 구조적으로 보장되기 때문이다. Depth 정보, Sibling Node의 순서, Traversing 성능이 중요한 경우 다른 모델을 고려해보는 것이 좋다.

  • Depth정보, Sibling Node의 순서, 간단한 쿼리 작성이 필요한 경우 Materialized Path모델을 선택하는 것이 좋다. 특히 Descendants Node를 조회하는 쿼리는 Leaf Node의 depth를 모르더라도, Self Join이 필요없는 Sargable Query라는 점이 특징적이다. 그러나 CHAR형태인path로 노드 사이의 관계를 정의하므로 Node의 갯수에 제한이 있다. 또한, Ascendants를 조회하는 쿼리는 IN operator를 요구하고 sargable하지는 않다.

  • 변경이 자주 없고 Traversing 성능이 중요한 경우 Nested Set 모델이 유리하다. descendant, ascendant 모두 간단한 sargable query로 조회할 수 있고, 노드의 갯수에 제한이 없다는 것이 장점이다. 그러나, 노드의 추가 삭제가 발생하는 경우 전체 노드에 대해 조회하고 수정하는 경우가 생기므로 cost가 크다.

django-treebeard 제공 API

  • add_root(self: Node,**kwargs) -> None
  • add_child(self: Node,**kwargs) -> None
  • add_sibling(self: Node, pos: int=None, **kwargs) -> None
  • move(target: Node, pos: int=None) -> None
    • subtree를 한번에 다른 노드 밑으로 이동시킬 때 사용
  • get_tree(self: Node, parent: Node=None) -> QuerySet[Node]
    • subtree에 대해 DFS를 통해 QuerySet 반환
profile
Ben

0개의 댓글