2012-01-04 2 views
3

우리는 두 개의 엔티티 User와 Role을 가지고 있습니다. 한 사용자는 여러 역할을 가질 수 있으며 단일 역할은 많은 사용자가 공유 할 수 있습니다. 전형적인 m : n 관계. 역할도 동적이며 많은 양 (수백만)을 기대합니다.카산드라 공유 레코드 (m : n) 디자인 패턴

관계형 DB에서 이러한 데이터를 모델링하는 것은 간단합니다. 나는 카산드라에서 가능할 때마다 알아보고 싶습니다.

역할을 참조하는 사용자 기록 외래 키의 각 하나의 별도의 CF 역할 및 저장소를 생성 조인 내부 표준화 된 모델을 사용하여 비슷한을 만들

A) :

현재 나는이 개 솔루션을 참조 .

프로 : 역할이 복제 및 유지 보수가

콘트라 간단되지 않습니다를 단일 사용자 다중 네트워크 통화에 대한 모든 역할을 얻기 위해 필요하다. 사용자 레코드는 FK 만 포함하고, 역할은 랜덤 파티셔너를 사용하여 으로 저장됩니다.이 경우 각 역할은 서로 다른 cassandra 노드에 저장 될 수 있습니다.

B) 모델을 비정규 및 왕복 카산드라에서이 시나리오 사용자 레코드에 사본으로 모든 사용자 역할을 포함하지 않도록하는 역할을 복제합니다.

pro : 단일 쿼리 내에서 모든 역할을 가진 사용자를 읽을 수 있습니다. 이는 짧은로드 시간을 보장합니다.

역주 : 각 공유 역할은 각 관련 사용자별로 여러 번 복사됩니다. 역할을 유지하는 것은 매우 어렵습니다. 특히 데이터 량이 많은 경우 특히 그렇습니다. 예를 들어 하나의 역할은 1000 명의 사용자가 공유합니다. 이 역할의 변경 사항은 1000 개의 사용자 레코드에 대한 업데이트가 필요합니다. 매우 큰 데이터 세트의 경우 이러한 업데이트를 비동기 작업으로 실행해야합니다.

위의 해결 방법은 매우 제한적이므로 meybie Cassandra는 m : n 관계에 대한 올바른 해결책이 아닙니까? 그런 문제에 대한 카산드라 디자인을 알고 있습니까?

덕분에, 마치에이

답변

2

당신이 카산드라의 데이터 저장소를 설계 할 방법은 start with the queries you plan to execute로하고 그렇게 당신이 한 번에 필요한 모든 정보를 얻을 수 있습니다합니다. 비정규 화는 게임의 이름입니다. 각 사용자 노드에서 해당 역할 정보를 복제하지 않으면 디스크 검색을 피할 수 없으며 읽기 성능이 저하됩니다. 조인은 의미가 없습니다. 관계형 데이터베이스를 원하면 관계형 데이터베이스를 사용하십시오.

사용자가 어떤 역할을하고 무엇을해야하는지에 대해 많은 질문을 할 것이므로 각 사용자 항목에 역할 정보가 중복되도록하고 싶을 것입니다. 자체 열을 가져 오는 역할 (roles => [serialized array of capability info] 대신 role-ROLE_KEY => serialized-capability-info). 응용 프로그램은 모든 열 자체를 반복 할 수있는 방법이 필요합니다.

사용자는 역할에 어떤 역할이 있는지 살펴보고, 해당보기에 필요한 모든 사용자 정보를 역할 열 가족에도 저장해야합니다 (전체 사용자의 하위 집합이기는하지만). 기록 할 것이다).

업데이트를 실행하고 역할에서 사용자를 추가/제거 할 때 역할의 사용자 목록과 사용자 역할을 동시에 업데이트해야합니다. 하나의 공유 직렬화 된 BLOB 대신 각 관계에 대해 열을 사용하기 때문에 동일한 사용자를 동시에 공유하는 두 개의 서로 다른 역할을 편집하는 경우에도 Cassandra가 삭제를 포함하여 업데이트를 병합 할 수 있습니다 .

쿼리가 비동기적일 필요가있는 경우 응용 프로그램에서 처리하도록하십시오. 카산드라는 궁극적 인 일관성 데이터 저장소이므로 언제 어디서나 즉시 업데이트를 볼 수는 없습니다.

+1

카산드라 결국 일관성이 될 수 있지만 그럴 필요하지 않습니다. 더 나은 설명은 복제 요소 및 읽기 및 쓰기 일관성 수준 ([R + W> 일관성 수준은 강력한 일관성을 제공합니다] (http://wiki.apache.org/cassandra/API#ConsistencyLevel)에 따라 조정 가능한 일관성을 유지한다는 것입니다.) – psanford

+0

대단한 답변에 감사드립니다! - 그럴 줄 알았어. 저의 경우 그러한 역할을 유지하는 것은 고통 스러울 것입니다 - 특히 수백만 명의 사용자가 공유하는 역할을 업데이트해야 할 때 ....하지만 다른 옵션도 없습니다. –

1

요즘 또 다른 옵션은 조인을 할 수있는 playORM을 사용하는 것입니다. 데이터를 분할하는 방법을 결정할뿐입니다. Scalabla JQL은 다음과 같이 JQL에 간단한 추가 기능을 사용합니다.

@NoSqlQuery (name = "findJoinOnNullPartition", query = "PARTITIONS t ('account', : partId) 선택 t INNER JOIN t.security s.securityType = : type 및 t.numShares = : shares ")

이렇게하면 noSQL 시스템에서 데이터를 정규화하고 동시에 크기를 조정할 수 있습니다. 우리는 어떤 이점을 갖는 정규화를 포기할 필요가 없습니다.