키 값 데이터베이스에서 중첩 항목을 효율적으로 쿼리하기 위해 스키마를 어떻게 설계합니까?

StackOverflow https://stackoverflow.com/questions/607746

문제

Erlang과 함께 Mnesia를 사용하고 있지만이 질문은 CouchDB 등과 같은 주요 값 DB에 적용됩니다.

나는 RDBMS 사고 과정에서 벗어나려고 노력하고 있지만 이러한 종류의 스키마를 효율적으로 구현하는 방법을 둘러싼 머리를 감싸지 못합니다.

사용자 레코드가 있고 많은 Subitema 레코드가 있는데, 많은 Subitem B 레코드가 있습니다.

User
-SubItem A
--SubItem B
...

Subitem B에서 쿼리를 실행해야합니다.이 중첩 일 때 수행하는 것이 효율적입니까? 더 빨리 정상화해야합니까?

데이터 복제를 사용하는 일부 사람들에 대해 들었으므로 데이터가 중첩되고 분리되어 있습니다. 이것은 우스운 일입니까 아니면 어떤 경우에는 실제로 유용합니까?

도움이 되었습니까?

해결책

근본적인 질문은 성능이 언제입니까? 충분하다?

테이블 스캔하는 모든 서브 하위 B를 세부적으로 검사 해야하는 경우 사용자 사전은 과도한 오버 헤드가 아닙니다. B의 크기는 사전의 전체 크기를 지배합니다.

충분하지 않은 경우, 모든 사용자의 읽기를 피하고 하위 요소 B를 쿼리 할 때 데이터를 편집 할 수 있도록 정규화하십시오. B의 (userId, subitemaid, subitembid)와 같은 복합 키를 사용하십시오. 사전 테이블을 주문한 경우 범위 쿼리를 수행 할 수 있습니다.

사용자/서브 이템 쿼리 성능을 완전히 죽이면 데이터 복제를 오류가 발생하기 쉽기 때문에 최후의 수단으로 고려하십시오.

다른 팁

CouchDB에서는 각 하위 항목에 대한보기 항목을 방출하는 것이 사소한 일입니다. 이것은 해당 항목에 매우 빠르게 액세스 할 수 있습니다. 보기 항목에 넣은 내용에 따라 부모 문서 / 하위 항목에 다시 연결하는 데 필요한 정보를 제공 할 수 있습니다.

나는 Mnesia에 대해 확신하지 못하고 CouchDB를 시작하고 있지만, 내 이해는 CouchDB에서 자신의 사용자 정의 색인 ( "보기")을 생성하기 때문에 하위 하위에 대한 인덱스를 간단하게 구축 할 수 있다는 것입니다. 항목.

예제 맵 함수 :

function(doc) {
    for(var i in doc.subitems_a) {
        var subitem_a = doc.subitems_a[i];

        for(var j in doc.subitems_a[item_a].subitems_b) {
            var subitem_b = subitem_a.subitems_b[j];

            emit(subitem_b, doc)
        }
    }
}

이는 효과적으로 Subitem BS의 인덱스 된 목록이며 선택한 목록에서 자르고 스플 라이스 할 수 있습니다.

실제로 그것은 내가 생각하는 데이터베이스에 따라 다릅니다. Couchdb에서는 한 가지가 더 잘 작동하는 동안 Mnesia에서는 다른 것이 더 나을 것입니다. 데이터를 분할하고 샤드해야합니까? 어떤 기준에 따라 그렇게해야합니까? 얼마나 많은 데이터 복제가 충분합니까?

Jeffery Hantin이 말했듯이 올바른 솔루션을 파악하기 위해 실험과 분석이 필요할 것이라고 말했습니다. 그것은 대부분의 비 관계형 데이터베이스가 문제를 해결하는 데 필요한 도구를 제공한다고 말했다. 귀하의 역할은 각각의 상충 관계를 파악하고 다른 사람과 비교할 수있는 상충 관계를 파악하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top