2012-10-05 4 views
10

그래프 데이터베이스에 접속하는 중입니다. "노드 유형"과 같은 항목을 추적하는 데 "색인 노드"또는 "색인 된 속성"을 사용하는 것을 결정하는 문제가 계속 발생하는 것 같습니다. 지금까지 실제 경험이 없기 때문에 결정을 내리는 데 필요한 정보가 없으며 두 가지 방법 모두 똑같이 유효합니다.그래프 데이터베이스에서 인덱스 노드 또는 인덱싱 된 속성이 더 좋은 이유는 무엇입니까?

따라서 질문은 다음과 같습니다. 두 가지 접근 방식 간의 장단점은 무엇이며 규모 (즉, 노드 수)가 결정에 어떤 영향을 미칩니 까? UserProduct 및 사용자 노드 사이의 가장자리와 제품 노드가 너무 많은 문제가되지 않지만, 우리가 걱정하는 경우입니다 : 샘플 시나리오의

는이 두 개의 "일"의 유형은 가정 수 있습니다 각 노드에서 type: Usertype: Product 속성을 원하거나 각 노드가 각각 User 노드와 Product 노드를 가리키는 가장자리를 갖기를 원할 경우

어느 상황에서 어떤 접근 방법이 더 좋습니까?

참고 : 특히 Neo4j와 Titan을보고 있지만이 방법이 더 일반적으로 적용되는 경향이 있습니다.

답변

18

먼저

start s = node:User(name='Bob') match s-[r]-(product)-[typeRel:PRODUCT]->() return product 

HTH처럼 -traversal, 당신은 스스로에게 물어해야합니다 가 정점/노드의 유형을 인덱싱 할 필요가 있는가? 즉, 유형별로 정점/노드를 검색해야합니까, 예를 들어 그래프에서 모든 '사용자'정점을 검색하거나 주어진 유형의 모든 정점을 검색하여 시작한 쿼리에 응답 한 다음 추가 필터링/처리해야 할 필요가 있습니까?

이 질문에 대한 대답이 인 경우 해당 유형을 색인화 된 문자열 속성으로 저장하는 것이 좋습니다. 또는 jvm 기반 언어로 개발하는 경우 유형 enum을 정의하고이를 유형 안전성 및 자동 오류 검사를위한 속성 유형으로 사용할 수 있습니다. Titan은 임의의 사용자 정의 클래스/열거 형을 속성 유형으로 지원하고 메모리 부족으로 압축합니다.

그러나이 방법의 단점은 낮은 선택도 색인을 작성하기 때문에 이것이 확장되지 않는다는 것입니다. 즉, '사용자'또는 '제품'유형의 정점이 매우 많으며 '사용자'또는 '제품'의 색인 항목과 각각 연관되어야하는 모든 정점이있을 것입니다. 이것은이 인덱스를 유지 보수하고 쿼리하는 것을 매우 비싸고 어렵게 만든다. (facebook이 'type'인덱스를 가지고 있다고 상상해 보라 : 'photo'엔트리는 그것 아래에 수십억 개의 정점을 가질 것이다). 스케일링과 관련이 없다면, 이것이 가능합니다.

질문에 대한 대답이 아니요 인 경우 그래프에서 모델 유형을 정점/노드로 제안합니다. 나는. '사용자'정점과 '제품'정점 및 각 사용자에서 '사용자'정점에 이르는 '유형'이라는 모서리가 있습니다.

이 방법의 장점은 그래프를 사용하여 데이터를 모델링하는 것입니다 데이터베이스 외부의 문자열 값을 가지기보다는 중요한 유형 정보를 나타냅니다. 응용 프로그램을 빌드 할 때 그래프 데이터베이스는 핵심 구성 요소가되고 오랜 기간 동안 지속됩니다. 프로그래밍 언어와 개발자가 출현하면서 데이터 모델링 및 유형 정보가 함께 전달되고 "SPECIAL_USER는 무엇을 의미합니까?"라는 질문에 직면하지 않아야합니다. 오히려 SPECIAL_USER 정점을 가져 와서 원본 정보 (즉, 누가이 유형을 작성했는지, 무엇을 나타내는 지, 짧은 설명인지 등)를 데이터베이스에 추가하십시오.

이 접근법의 한 가지 문제점은 '사용자'및 '제품'정점이 응용 프로그램의 확장에 따라 많은 양의 가장자리를 갖게된다는 것입니다. 즉, 스케일링 문제를 생성하는 슈퍼 노드를 생성하는 것입니다. 이것이 Titan이 단방향 에지의 개념을 도입 한 이유입니다. 단방향 에지는 웹상의 링크와 같습니다. 시작점은 다른 꼭지점을 가리 킵니다. 그러나 그 꼭지점은 가장자리를 인식하지 못합니다. '사용자'버텍스에서 모든 사용자 버텍스로 이동하고 싶지 않으므로 아무 것도 잃어 버리지 않고 확장 성 및 성능을 확보 할 수 있습니다.

+0

요약하면 인덱스 된 속성을 사용하면 확장 성을 희생하면서 더 쉽게 모든 노드 유형을 사용할 수 있으며 인덱스 노드를 사용하면 확장 성을 희생하여보다 자연스러운 (즉 구조적) 표현이 가능합니다. . 어떤 방법으로 그래프를 사용할 수있는 방법이 실질적으로 제한됩니까? – cdeszaq

+0

나는 당신을 쫓고 있는지 확신하지 못합니다. 사용자가 두 번째 솔루션을 사용하도록 권고 한 경우 (따라서 유형을 지정하기 위해 가장자리를 사용하는 경우) 어떻게 사용자 목록을 찾을 수 있습니까? 사용자 정점에서 사용자 목록으로 이동할 수 없으므로 ... –

+0

위대한 답변을 주셔서 감사합니다. 하지만 '사용자'노드에 대해 단방향 에지를 사용하는 것에 대해 좀 더 자세히 이야기 할 수 있습니까? 각 방향에서 질의하는 측면에서 그 의미는 무엇입니까? (나는 인덱스 속성을 가장자리에 추가하지 않는 한 아무 것도, 그리고 큰 영향을 미쳤다.)또한 Cassandra를 사용하면 단방향 에지를 사용하여 수백만 개 노드의 '사용자'유형으로 제한 할 수 있습니다. –

4

어떤 종류의 질문을 하시겠습니까? Neo4j, 당신은 UserProduct 인덱스를 만들 것 또는 하나에 그들을 결합하고

start bob = node:User(name='Bob') match .... 

심지어 전체 텍스트 검색 같은 것들을 질문 할 수 있습니다. 노드가 사용자 또는 제품인지 쉽게 확인하기 위해 편리하고 빠른 탐색을 위해 노드에 속성을 유지할 수 있습니다. User/Product에서 인스턴스 노드로 이동하지 않는 경우 (인덱스 검색을 수행하는 경우) PRODUCT 또는 USER 관계를 유형 (수퍼) 노드로 되돌려 주면서 체크를 할 수도 있습니다

0

색인 생성에 대한 매우 중요한 이유가 여기에 누락되었습니다. 많은 다른 속성과 많은 다른 노드 유형을 가진 복잡한 그래프가 있다고 가정하고 패턴을 속성이 많은 "사람"과 일치 시키려고합니다.

인덱스가없는 경우 노드의 0.01 % 만 사람 인 유형의 그래프를 탐색 할 수있는 옵션이 없습니다. 그리고 횡단은 그래프의 연결되지 않은 영역에 도달하지 않을 수 있습니다.

대신 색인 된 사람이있는 경우 모든 사람을 반복하고 각 사람의 주변을 검색하여 패턴이 일치하는지 확인합니다.

이 방법 중 첫 번째 방법이 그래프의 전체 크기에 비례하지만 두 번째 방법은 그래프에있는 전체 사람 수로 조정된다는 것을 즉시 알 수 있어야합니다.

도덕적 : 패턴의 바운드 노드로 특정 유형의 노드 (예 : 여기에 "패턴 X가있는 사람들"에 대한 검색)가 많은 그래프를 검색 할 유스 케이스를 생각한다면 검색 성능을 향상 시키려면이 노드를 색인화해야합니다.

"사람 피터의 두 링크 내의 모든 노드"와 같은 것을 검색하려는 경우 이름을 기준으로 사람을 인덱싱하는 것이 중요하며 본질적으로 찾고있는 것처럼 그래프 크기에 관계없이 일정한 성능을 유지할 수 있습니다 피터의 위치를 ​​해쉬 테이블에 올리십시오.

+0

질문은 'personName'과 같은 자유형 속성이 아닌'nodeType'과 같은 개별 속성에 초점을 맞추고 있습니다. 따라서 Peter의 노드를 찾는 요지는이 질문에 영향을주지 않습니다. 그러나 자유 형식 자산을 색인하는 유일하고 합리적인 방법은 전통적인 색인을 사용하는 것이므로 차별화하는 것이 좋습니다. – cdeszaq

+0

또한, 노드의 .01 %를 처리하는 방법에 대한 질문이 정확합니다. 문제는 "인덱스 노드가 nodeType과 같은 개별 필드의 전통적인 인덱스보다 어느 시점에 더 많은/덜 이해하게되는지"입니다. 문제는 색인 생성을위한 _ 이유에 관한 것이 아니라 언제 어떤 방법으로 색인을 생성하는 것이 더 효과적인지, 언제 그리고 왜 그런가? – cdeszaq