2013-12-22 6 views
0

RavenDb에서 계층 적 데이터를 저장해야하며 재귀 적으로 쿼리해야합니다. 성능이 가장 큰 걱정거리입니다.RavenDb의 계층 적 데이터 모델링

내가 가지고하면 다음 하나와 유사한 :

public class Category 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public Category Parent { get; set; } 
} 
이 경우

, 나는 문서 자체 내부의 상위 범주를 저장하는 경우, 그것은 제가이 중복되므로 데이터를 관리하기 어려운 것임 카테고리 전체에 카테고리가 있습니다.

그래서, 즉 쉽게하기 위해 나는 아래이를 저장할 수 있습니다 :

public class Category 
{ 
    public int Id { get; set; } 
    public int? ParentId { get; set; } 
    public string Name { get; set; } 
} 

을하지만,이 경우에 나는 기록의 수백만해야합니다 내가 필요로하는 성능이 여기에 얼마나 확실하지 않다 이 참조에서 범주 트리를 만들 수 있습니다.

성능이 가장 큰 문제인 경우 RavenDb에서 이러한 유형의 데이터를 모델링하는 방법에 대한 결정이 있습니까?

답변

4

계층 구조는 일반적으로 계층 구조를 정의하는 하나의 문서에서 가장 잘 모델링됩니다. 귀하의 상황에서는 범주 트리를 정의하는 것이고, 범주 자체는 독립형 문서로 표현 될 수 있으므로 (예 : 이름, 설명 등을 보유하고 다른 콜렉션이이를 참조 할 수 있도록 허용), 그렇지 않을 수 있습니다. 코드에서 모델로

카테고리 문서 같은 것을 보일 것이다 :

public class Category 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    // other meta-data that you want to store per category, like image etc 
} 

그리고 계층 구조 트리 문서가이 클래스는 쉽게에서 노드를 만들기위한 방법을 가질 수있는 다음과 같은 클래스에서 직렬화 할 수 있습니다 접근 :

public class CategoriesHierarchyTree 
{ 
    public class Node 
    { 
     public string CategoryId { get; set; } 
     public List<Node> Children { get; set; } 
    } 

    public List<Node> RootCategories { get; private set; } 

    // various methods for looking up and updating tree structure 
} 

계층 구조 트리의이 방법은 몇 가지 중요한 장점이 있습니다

  1. 하나의 트랜잭션 범위 - 트리가 변경되면 트리가 항상 하나의 트랜잭션에서 변경됩니다. 이 문서를 편집 할 때 낙관적 동시성을 활용할 수 있기 때문에 트리에 대한 여러 동시 변경의 영향을받을 수 없습니다. 제안한 방식을 사용하면 시간이 지남에 따라 계층 구조 트리의 완전성과 정확성을 보장하기가 더 어렵다는 것을 보장하는 것은 불가능합니다. 계층 구조를 트리라고 생각하면 실제로 완료 될 때까지 각 변경 내용이 전체 트리를 잠그는 것이 좋습니다. 계층 트리는 하나의 엔티티입니다.
  2. 캐싱 - 적극적인 캐싱을 사용하는 경우에도 전체 계층 구조를 신속하고 효율적으로 캐싱 할 수 있으므로 계층 구조에 대한 쿼리로 서버에 액세스하는 시간을 최소화 할 수 있습니다.
  3. 모든 작업은 완전히 하나의 문서, 일명 개체, 계층 구조의 모든 쿼리 (부모 목록, 자식 목록 등)가 전체적으로 메모리에 만들어지기 때문에 수행 할 작업에 거의 가깝지 않습니다. . 이러한 쿼리에 응답하기 위해 Recurse()가있는 인덱스를 사용하면 비용이 더 많이 소요됩니다 (네트워크 비용 및 계산). 실적이 가장 큰 관심사라고 말하면 이것이 우승자입니다.
  4. 범주 당 여러 개의 부모, 비정규 화 없음 - 범주 문서가 위와 같이 계층 구조 트리 외부에 저장되는 경우 비정규 화하지 않고 여러 부모 아래 범주를 효과적으로 배치 할 수 있습니다. 모든 범주 데이터는 트리 외부의 문서에서 한 위치에 있으며 트리는 범주에 대한 참조 만 보유합니다.

이 접근 방법을 적극 권장합니다. 관계형 사고에서 조금 벗어나지 만 그만한 가치가 있습니다. 나무가 커질 때에도 마찬가지입니다.

+0

감사합니다. 이것은 정말로 도움이됩니다. 이 경우 여러 범주 (1000 번, 누가 아는 지)에서 범주를 복제합니다. 따라서 RavenDb에서 여러 범주의 카테고리 정보를 업데이트하는 방법이 있습니까? 또는 하나씩 찾아서 개별적으로 업데이트해야합니까? 배치 업데이트 (http://ravendb.net/docs/2.0/client-api/set-based-operations)를 보았지만 이것이 필요한지 확실하지 않습니다. – tugberk

+0

나는 다음과 같지 않습니다 - 왜 카테고리의 여러 항목을 한꺼번에 업데이트해야합니까? 내가 제안한 바에 따르면 문서의 카테고리는 한 번만 나오고 계층 트리는 카테고리 ID를 사용하여 부모가 누구인지 정의 할 수 있습니다. 둘 이상일 수 있습니다. – synhershko

+0

내가이 문제로 생각하는 한 가지, 그리고 분명히 이것은이 스타일에 대한 나의 새로운 것이고 특정 카테고리의 ID가 주어지며 어떻게 모든 아이들을 얻을 수 있습니까? 루트로 돌아가는 경로를 알지 못하는 한 계층 구조를 쿼리 할 수 ​​없기 때문에 부모를 쉽게 얻을 수 있습니다. 이것은 다른 쪽을 향한 하나의 순회 방향의 우선 순위를 바꾸는 것이 아닌가? – MarqueIV