2014-04-19 2 views
28

mongo db에서 복합 기본 키를 처리하는 가장 좋은 방법을 결정하려고합니다. 이 시스템의 데이터와 상호 작용하기위한 주요 열쇠는 2 개의 uuids로 구성됩니다. uuids의 조합은 고유 한 것으로 보장되지만 개별 uuids도 마찬가지입니다.MongoDB 및 복합 기본 키

  1. 가 (here를 제안)이 개 값

  2. 를 사용하여 표준 자동으로 만들어지는 기본 키 객체를 사용

    나는이를 관리하는 몇 가지 방법을 참조 생성 된 mongo 객체 ID를 기본 키로 생성하고, 두 개의 개별 필드에 내 키를 저장 한 다음,이 두 필드에 복합 색인을 생성하십시오.

  3. 기본 키를 2 uuids의 해시

  4. 내가 현재 이러한 방법의 성능에 미치는 영향은 무엇

모르고 나는 다른 어떤 멋진 솔루션?

옵션 1의 경우 순차적 키가 아닌 것에 대한 삽입 성능이 걱정됩니다. 나는 이것이 전통적인 RDBMS 시스템을 죽일 수 있다는 것을 알고 있으며 MongoDB에서도 이것이 사실 일 수 있다는 징후를 보았습니다.

옵션 2의 경우 시스템에서 사용하지 않는 기본 키를 사용하는 것이 약간 이상한 것 같습니다. 또한 쿼리 성능이 옵션 1만큼 좋지 않을 수 있습니다. 전통적인 RDBMS에서는 클러스터 된 인덱스가 최상의 쿼리 결과를 제공합니다. MongoDB와 얼마나 관련이 있습니까?

옵션 3의 경우 단일 ID 필드를 만들지 만 삽입 할 때 다시 순차적이지는 않습니다. 이 접근법에 대한 다른 장단점이 있습니까?

옵션 4의 경우 ... 옵션 4는 무엇입니까?

MongoDB 대신 CouchDB를 사용하는 것에 대한 논의도 있습니다. CouchDB를 사용하면 다른 해결책을 제시 할 수 있습니까?

MORE INFO : 문제에 대한 몇 가지 배경을 찾을 수 있습니다 나는 당신은 여전히 ​​모두 UUID 필드를 처리하는 인덱스를 만들 수 있습니다 옵션 2로 갔어요 것이고, 성능은 동일해야 here

+1

아마도 가장 중요한 질문은이 데이터에 어떻게 액세스 할 예정입니까? 분명히 삽입 - 업데이트를 쓰고 있습니까? 쿼리는 어떨까요? 이제까지 삭제? –

+0

주로 쓰고 있습니다. 그런 다음 업데이트합니다 (대부분 큰 버스트). 상당한 수의 삽입물 (다시, 대부분 큰 폭발음). 비정기 삭제. – herbrandson

+0

업데이트를 사용할 필드는 무엇입니까? 하나 또는 둘 다? –

답변

28

1.

주된 이유는 성능에 대해 걱정하고 있다는 것입니다. 주된 이유는 성능에 대해 걱정할 필요가 있다는 것입니다. 항상 존재하고 이미 고유 한 _id 인덱스를 사용하면 두 번째 고유 인덱스를 유지해야하는 부담을 줄일 수 있습니다.

옵션 1의 경우, 삽입 성능이 순차 키가 아닌 것으로 걱정됩니다. 나는 이것이 전통적인 RDBMS 시스템 인 을 죽일 수 있다는 것을 알고 있으며 MongoDB에서도 이것이 사실 일 수 있다는 표시를 보았습니다.

귀하의 다른 옵션은 단지 보조 고유 인덱스에 _id 지수에서 그것을 이동,이 문제를 방지하지 않습니다 -하지만 잘 균형 및 랜덤 액세스의 다른 하나 일단 지금은, 두 개의 인덱스가 있습니다.

옵션 1에 질문하는 이유는 하나뿐입니다. 즉, 하나 또는 다른 UUID 값으로 문서에 액세스하려는 경우입니다. 항상 두 값을 제공하는 한 (이 부분은 매우 중요 함) 모든 쿼리에서 항상 같은 방식으로 순서를 지정하면 _id 인덱스가 효율적으로 전체 용도로 사용됩니다. 하위 문서를 비교할 때 당신은 항상 두 개의 UUID는 같은 방법으로 값 주문 확인해야하는 이유에 정교으로

{ a:1, b:2 }{ b:2, a:1 } 동일하지 않습니다 - 당신이 두 문서는 _id를 위해 그 값을 가지고 컬렉션을 가질 수 있습니다. 따라서 _id에 필드를 먼저 저장하면 모든 문서와 쿼리에 항상 그 순서를 유지해야합니다.

다른주의가 _id:1에 인덱스가 쿼리에 사용할 수있을 것입니다 :

db.collection.find({_id:{a:1,b:2}}) 

하지만 쿼리에 대해 사용할 수 없습니다

db.collection.find({"_id.a":1, "_id.b":2}) 
+0

안녕하세요, 복합 기본 키를 구현하는 방법을 보여 주실 수 있습니까? 지금 당장하고있는 일은'StringJoiner joiner = new StringJoiner ("/"); \t \t \t joiner.add (info.getUserID()). add (idOfApp); \t \t \t String idName = joiner.toString();'그리고 잘 작동하지만 복합 키를 사용하는 것이 훨씬 더 나은 접근 방법이며 BasciDBObject를 사용하고 필드의 두 값을 추가하여 시도했지만 그것은 작동하지 않았다. 어쩌면 내가 뭔가 잘못하고있는 것 같아. 따라서 완전한 구현을 보여줄 수 있다면 큰 도움이 될 것입니다. 많은 감사드립니다. – Learner

+1

새로운 질문을 올리십시오, 이것은 의견에 적절하지 않습니다. –

+0

그래, 고마워, 내가 그걸 염두에 두겠다. 나는 실제로 그것을 스스로 알아 냈다. 'BasicDBObject compositeKey = new BasicDBObject ("deviceId", deviceID) .append ("id", id); \t \t \t \t \t \t 문자열 newID = compositeKey.toJson();'여기서 deviceID와 id는 내가 추가해야하는 값을 포함합니다. 다시 한번 감사합니다. – Learner

2

복합 기본 키로 사용하는 것이 훨씬 쉽습니다.

또한 내 경험상, 엄격하게 요구되지는 않았지만 무언가 고유 한 ID를 부여한 것을 결코 후회하지 않았습니다. 아마 그것은 인기가없는 의견이다.

2

나는이 옵션에 가서 1에 제안 대신 모두의 UUID에서 연결된 하나의 두 개의 필드를 갖는 이유

  1. 이, 인덱스의 다른 조합을 만들 수있는 유연성을 떠날 것 미래의 질의 요청을 지원하거나 하나의 키의 카디널리티가 다른 키의 카디널리티보다 높다는 것을 알면됩니다.
  2. 비 순차적 키를 사용하면 샤드 환경에 삽입하는 동안 핫스팟을 피할 수 있으므로 좋지 않은 옵션입니다.쓰기 잠금은 데이터베이스 레벨 (2.6 이전) 또는 컬렉션 레벨 (2.6 버전)에 있기 때문에 샤딩은 내 생각에 컬렉션에 대한 삽입 및 업데이트를 조정하는 가장 좋은 방법입니다.
+0

감사합니다. 도움이됩니다. 명확히하기 위해 비 순차 키를 사용하면 환경을 보호하는 데 도움이 될 수 있습니다. 그러나 옵션 2는 순차적 ID를 제공 할 수있는 옵션입니다. 뭔가 이해 못 하겠니? – herbrandson

+0

맞습니다. 비 순차 키 주석은 RDBMS에서 순차 키가 도움이된다고 말한 귀하의 질문에 관련된 것입니다. – Boris

+0

대부분의 RDBMS에서 레코드는 기본 키 순서로 디스크에 물리적으로 저장됩니다. 비 순차 삽입을 수행 할 때 모든 레코드를 물리적으로 이동해야합니다. 이것이 인서트를 순차적이지 않은 ID로 느리게 만드는 이유입니다. 또한 클러스터 된 키에 대한 쿼리가 빠른 이유이기도합니다. (당신은 이미 그 사실을 알고있을 것 같았지만, 나는 단지 내 질문을 배경으로두고 싶었다.) MongoDB에서는 그렇지 않다는 말입니까? 저의 독서는 저를 여전히 고려 사항이라고 믿게했습니다. 나는 표준 MongoDB ObjectID가 순차적이라는 것을 안다. 나는 그것이 그 이유의 일부라고 생각했다. – herbrandson

6

내가 당신을 위해 옵션 4를 가지고 :

자동 _id 필드를 사용하고 단일 c 대신 두 개의 uuid에 대해 두 개의 단일 필드 색인을 추가하십시오. 누적 색인. (즉 MongoDB 덜 중요하지만)

  1. _id 지수는 쉽게 shardable 순차적 것입니다, 당신은 MongoDB이 그것을 관리 할 수 ​​있습니다.
  2. 2Uuid 인덱스를 사용하면 필요한 모든 종류의 쿼리를 만들 수 있습니다 (첫 번째 쿼리에서는 두 번째 쿼리 또는 두 번째 쿼리와 함께 모든 쿼리를 수행 할 수 있음).이 쿼리는 1 개의 복합 인덱스보다 적은 공간을 차지합니다.
  3. 동일한 쿼리에서 두 인덱스 (및 다른 인덱스 인덱스)를 모두 사용하는 경우 MongoDBintersect them (v2.6의 새로운 기능)은 마치 복합 인덱스를 사용하는 것과 같습니다.
+0

순차 인덱스를 샤딩하는 것은 나쁜 아이디어입니다. 모든 샤드에 균등하게 공유되지 않습니다 + 1 대신 2 개의 인덱스가 있기 때문에 쓸모없는 인덱스 공간이 채워질 것입니다 (대규모 컬렉션에서 큰 거래). –

+0

@JonathanMuller 해시를 사용하여 조각을 파기하지 않을 경우. "해시 키는 ObjectId와 같이 단조롭게 증가하는 필드와 잘 작동합니다"https://docs.mongodb.org/manual/core/sharding-shard-key/#sharding-hashed-sharding – i3arnon