해시 인덱스
이 페이지의 내용
해시된 인덱스는 인덱싱된 필드 값의 해시로 항목을 유지 관리합니다.
해시된 인덱스는 해시된 샤드 키를 사용한 샤딩을 지원합니다. 해시 기반 샤딩은 필드의 해시 인덱스를 샤드 키로 사용하여 샤딩된 클러스터에서 데이터를 분할합니다.
해시 샤드 키를 사용하여 collection을 샤딩하면 데이터가 더 고르게 분산됩니다. 자세한 내용은 해시 샤딩 을 참조하세요.
해싱 함수
해시된 인덱스는 해시 함수를 사용하여 인덱스 필드 값의 해시를 계산합니다. [1] 해싱 함수는 내장된 문서를 축소하고 전체 값에 대한 해시를 계산하지만 다중 키(예: 배열) 인덱스. 특히 배열이 포함된 필드에 해시된 인덱스를 만들 거나 해시된 인덱스 필드에 배열을 삽입하려고 하면 오류가 반환됩니다.
팁
MongoDB는 해시된 인덱스를 사용하여 쿼리를 해결할 때 해시를 자동으로 계산합니다. 애플리케이션은 해시를 계산할 필요가 없습니다.
[1] | 버전 4.0 부터 mongosh 는 convertShardKeyToHashed() 메서드를 제공합니다. 이 메서드는 해시된 인덱스와 동일한 해시 함수를 사용하며 키의 해시된 값을 확인하는 데 사용할 수 있습니다. |
해시 인덱스 만들기
해시된 인덱스 를 만들려면 다음 예제와 같이 인덱스 키의 값으로 hashed
를 지정합니다.
db.collection.createIndex( { _id: "hashed" } )
복합 해시 인덱스 만들기
버전 4.4에 추가되었습니다.
MongoDB 4.4부터 MongoDB는 단일 해시 필드를 포함하는 복합 인덱스 생성을 지원합니다. 복합 해시 인덱스를 만들려면 인덱스를 만들 때 단일 인덱스 키의 값으로 hashed
을 지정합니다.
db.collection.createIndex( { "fieldA" : 1, "fieldB" : "hashed", "fieldC" : -1 } )
복합 해시 인덱스를 사용하려면 featureCompatibilityVersion이 4.4
로 설정되어 있어야 합니다.
고려 사항
내장된 문서
해싱 함수는 내장된 문서를 축소하고 전체 값에 대한 해시를 계산하지만, 다중 키(예: 배열) 인덱스. 특히 배열이 포함된 필드에 해시된 인덱스를 만들 거나 해시된 인덱스 필드에 배열을 삽입하려고 하면 오류가 반환됩니다.
고유 제약 조건
MongoDB는 hashed
인덱스에 대한 고유 제약 조건 지정을 지원하지 않습니다. 대신 해당 필드에 고유 제약 조건이 있는 해시되지 않은 인덱스를 추가로 만들 수 있습니다. MongoDB는 해시되지 않은 인덱스를 사용하여 필드에 고유성을 적용할 수 있습니다.
2 53 Limit
경고
MongoDB hashed
인덱스는 해싱 전에 부동 소수점 숫자를 64비트 정수로 자릅니다. 예를 들어 hashed
인덱스는 2.3
, 2.2
, 2.9
값을 포함하는 필드에 대해 동일한 값을 저장합니다. 충돌을 방지하려면 64비트 정수로 안정적으로 변환한 다음 다시 부동 소수점으로 변환할 수 없는 부동 소수점 숫자에는 hashed
인덱스를 사용하지 마십시오. MongoDB hashed
인덱스는 2 53보다 큰 부동 소수점 값을 지원하지 않습니다.
키의 해시값이 무엇인지 확인하려면 convertShardKeyToHashed()
를 참조하세요.
PowerPC 및 2 63
해시된 인덱스 의 경우, MongoDB 4.2는 PowerPC 의 부동 소수점 값에 대한 해시된 값이 다른 플랫폼과 일치하도록 2 63
2 53 보다 큰 부동 소수점 값을 포함할 수 있는 필드의 해시된 인덱스 는 지원되지 않는 구성이지만, 클라이언트는 여전히 인덱싱된 필드의 값이 2 63 인 문서를 삽입할 수 있습니다.
배포의 모든 컬렉션에 대한 모든 hashed
인덱스를 나열하려면 mongosh
에서 다음 작업을 사용할 수 있습니다.
db.adminCommand("listDatabases").databases.forEach(function(d){ let mdb = db.getSiblingDB(d.name); mdb.getCollectionInfos({ type: "collection" }).forEach(function(c){ let currentCollection = mdb.getCollection(c.name); currentCollection.getIndexes().forEach(function(idx){ let idxValues = Object.values(Object.assign({}, idx.key)); if (idxValues.includes("hashed")) { print("Hashed index: " + idx.name + " on " + d.name + "." + c.name); printjson(idx); }; }); }); });
인덱싱된 필드에 2 63 값이 포함되어 있는지 확인하려면 collection과 인덱싱된 필드에 대해 다음 작업을 실행합니다.
인덱싱된 필드 유형이 스칼라이고 문서가 아닌 경우:
// substitute the actual collection name for <collection> // substitute the actual indexed field name for <indexfield> db.<collection>.find( { <indexfield>: Math.pow(2,63) } ); 인덱싱된 필드 유형이 문서(또는 스칼라)인 경우 다음을 실행할 수 있습니다.
// substitute the actual collection name for <collection> // substitute the actual indexed field name for <indexfield> db.<collection>.find({ $where: function() { function findVal(obj, val) { if (obj === val) return true; for (const child in obj) { if (findVal(obj[child], val)) { return true; } } return false; } return findVal(this.<indexfield>, Math.pow(2, 63)); } })