Docs Menu
Docs Home
/ /

Unique Indexes

고유 인덱스는 인덱싱된 필드의 값이 고유하도록 합니다.

  • 고유한 단일 필드 인덱스 지정된 필드 에 대해 값이 최대 한 번 표시되도록 합니다.

  • 고유한 복합 인덱스 사용하면 지정된 인덱스 키 값 조합이 최대 한 번만 표시됩니다.

기본값 으로 MongoDB 새 컬렉션 만들 때 _id 필드 에 고유인덱스 만듭니다.

MongoDB Atlas에서 호스팅되는 배포서버에 대해 UI에서 고유 인덱스를 생성하고 관리할 수 있습니다.

MongoDB Shell 에서 고유 인덱스 생성하려면 db.collection.createIndex() 옵션을 로 설정하다 하여 unique 메서드를 true 사용합니다.

db.collection.createIndex(
{ <field>: <sortOrder> },
{ unique: true }
)

고유 인덱스 만들려면 다음을 참조하세요.

컬렉션 고유 제약 조건을 위반하는 데이터가 이미 포함되어 있는 경우 MongoDB 고유 인덱스 직접 생성할 수 없습니다. 중복 값이 포함된 컬렉션 에 고유 인덱스 만들려면 prepareUnique 옵션을 사용할 수 있습니다.

중복 값이 포함된 컬렉션 에 prepareUnique 를 사용하려면 다음 단계를 따르세요.

  1. 고유성을 시행하다 하려는 필드 에 고유 인덱스 생성합니다.

  2. 명령을 collMod 사용하여 prepareUnique true 인덱스 에 대해 을 로 설정하다 .

    prepareUniquetrue로 설정하다 하면 인덱싱된 필드 에 대한 모든 새 쓰기에 대해 고유 제약 조건이 적용됩니다. 기존 중복 값은 제거되지 않습니다.

  3. 인덱싱된 필드 에서 기존 중복 값을 해결합니다.

  4. 인덱스 고유하게 만들려면 collMod 명령을 사용합니다.

prepareUnique 기능 중복을 제거하려는 중복 값이 있는 데이터 세트가 이미 있고 정리 프로세스 중에 새 중복 값이 추가되지 않도록 해야 하는 경우에 유용합니다.

를 사용하는 전체 예시 는 prepareUnique 기존 인덱스를 고유 인덱스로 변환을 참조하세요.

복제본 세트 및 샤딩된 클러스터의 경우 롤링 절차를 사용하여 고유 인덱스를 만들려면 절차가 진행되는 동안 컬렉션에 대한 모든 쓰기를 중지해야 합니다. 절차가 진행되는 동안 컬렉션에 대한 모든 쓰기를 중지할 수 없다면 롤링 절차를 사용하지 마세요. 대신, 컬렉션에서 고유 인덱스를 구축하려면 다음 중 하나를 수행해야 합니다.

  • 복제본 세트의 프라이머리에서 db.collection.createIndex() 실행

  • 샤딩된 클러스터의 경우 mongos에서 db.collection.createIndex() 실행

고유 제약 조건은 컬렉션의 개별 문서에 적용됩니다. 즉, 고유 인덱스는 별도의 문서가 인덱스된 키에 대해 동일한 값을 갖는 것을 방지합니다.

제약 조건은 개별 문서에 적용되므로 고유한 멀티키 인덱스의 경우 문서에 배열 요소를 가질 수 있으며, 해당 문서의 인덱스 키 값이 다른 문서의 인덱스 키 값과 중복되지 않는 한 인덱스 키 값이 반복될 수 있습니다. 이 경우 반복되는 인덱스 항목은 인덱스에 한 번만 삽입됩니다.

예시 들어 제품 및 해당 주식 위치를 나타내는 다음 문서가 포함된 inventory 컬렉션 가정해 보겠습니다.

db.inventory.insertMany( [
{ _id: 1, product: "pencils", inventory: [ { warehouse: "NYC", quantity: 5 }, { quantity: 10 } ] },
{ _id: 2, product: "pens", inventory: [ { warehouse: "NYC" }, { quantity: 5 } ] },
{ _id: 3, product: "markers", inventory: [ { warehouse: "NYC", quantity: 10 } ] }
] )

inventory.warehouseinventory.quantity에 고유한 복합 멀티키 인덱스를 생성합니다.

db.products.createIndex( { "inventory.warehouse": 1, "inventory.quantity": 1 }, { unique: true } )

고유 인덱스는 컬렉션의 다른 문서가 인덱스 키 값 { "inventory.warehouse": "LA", "inventory.quantity": null }을 가지고 있지 않는 경우, 다음 문서를 컬렉션에 삽입하는 것을 허용합니다.

db.products.insertOne( { _id: 4, product: "Sprocket", inventory: [ { warehouse: "LA" }, { warehouse: "LA" } ] } )

고유한 단일 필드 인덱스에서 인덱싱된 필드에 대해 문서가 null 값이거나 누락된 경우, 인덱스는 해당 문서에 대해 null 값을 저장합니다. 고유 제약조건으로 인해 단일 필드 고유 인덱스는 해당 인덱스 항목에 null 값을 포함하는 하나의 문서만 포함할 수 있습니다. 인덱스 항목에 null 값이 있는 문서가 두 개 이상 있으면 중복 키 오류로 인해 인덱스 빌드가 실패합니다.

예를 들어 컬렉션에 x에 대한 고유한 단일 필드 인덱스가 있습니다.

db.collection.createIndex( { "x": 1 }, { unique: true } )

컬렉션에 x 필드가 누락된 문서가 아직 포함되어 있지 않은 경우, 고유 인덱스는 x 필드 없이 문서의 삽입을 허용합니다.

db.collection.insertOne( { y: 1 } )

그러나 컬렉션에 x 필드가 없는 문서가 이미 포함되어 있는 경우 필드 x 없이 문서를 삽입할 수 없습니다.

db.collection.insertOne( { z: 1 } )

x 필드 값에 대한 고유 제약 조건 위반으로 인해 작업이 문서를 삽입하지 못했습니다.

WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error index: test.collection.$a.b_1 dup key: { : null }"
}
})

고유 복합 인덱스에서 하나 이상의 인덱스된 필드에 대해 문서가 null 값을 가지거나 값이 누락된 경우, 인덱스는 문서의 인덱스 항목에서 각 null 또는 누락된 필드에 대해 null 값을 저장합니다. 고유한 제약 조건으로 인해 고유한 복합 인덱스는 인덱스 항목의 모든 인덱스 필드에 대해 null 값을 가진 문서 하나만 허용합니다. 모든 인덱싱된 필드에 null 값이 있는 인덱스 항목이 두 개 이상 있는 경우 중복 키 오류가 발생하여 인덱스 작성이 실패합니다. MongoDB는 각 인덱스 항목이 고유하기만 하면 고유 복합 인덱스에 누락된 필드가 있는 여러 문서를 허용합니다.

예를 들어 컬렉션 studentsname, agegrade 필드에 고유한 복합 인덱스를 가지고 있습니다:

db.students.createIndex(
{
"name": 1,
"age": -1,
"grade": 1
},
{ unique: true }
)

컬렉션에 동일한 문서가 아직 없는 경우 고유 복합 인덱스는 grade 필드가 모두 없는 다음 문서를 삽입을 허용합니다.

db.students.insertMany( [
{ "name": "Meredith", "age": 12 },
{ "name": "Olivia", "age": 11 },
{ "name": "Benjamin" }
] )

그러나 컬렉션의 다른 문서와 동일한 인덱스 키 (name, agegrade의 값)을 가진 문서는 삽입할 수 없습니다.

db.students.insertOne( { name: "Meredith", age: 12 } )

name, agegrade 필드 값에 대한 고유 제약 조건 위반으로 인해 작업이 문서 삽입 작업이 실패합니다.

WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" :
"E11000 duplicate key error collection: test.students
index: name_1_age_-1_grade_1
dup key: { name: "Meredith", age: 12, grade: null }
}
} )

또한, 문서가 고유하지만 기존 인덱스 항목과 인덱스 키를 공유하는 경우에도 문서를 삽입할 수 없습니다.

db.students.insertOne( { name: "Olivia", "age": 11, "favorite color": "red"} )

name, agegrade 필드 값에 대한 고유 제약 조건 위반으로 인해 작업이 문서 삽입 작업이 실패합니다.

WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" :
"E11000 duplicate key error collection: test.students
index: name_1_age_-1_grade_1
dup key: { name: "Olivia", age: 11, grade: null }
}
} )

부분 인덱스는 지정된 필터 표현식을 충족하는 컬렉션의 문서만 인덱싱합니다. partialFilterExpression과(와) 고유 제약 조건을 모두 지정하는 경우 고유 제약 조건은 필터 표현식을 충족하는 문서에만 적용됩니다.

고유 제약 조건이 있는 부분 인덱스는 문서가 필터 기준을 충족하지 않는 경우 고유 제약 조건을 충족하지 않는 문서의 삽입을 막지 않습니다. 이에 대한 예시는 고유 제약 조건이 있는 부분 인덱스를 참조하세요.

해시 인덱스에는 고유한 제약 조건을 지정할 수 없습니다.

범위가 지정된 샤딩된 컬렉션의 경우 다음 인덱스만 고유할 수 있습니다.

  • 샤드 키 의 인덱스 .

  • 샤드 키 접두사인 복합 인덱스 입니다.

  • _id 기본값 인덱스. 그러나 인덱스 _id _id 필드 샤드 키 아닌 경우에만 샤드 당 고유성 제약 조건을 적용합니다.

중요

_id 필드가 샤드 키가 아닐 경우 샤딩된 클러스터는 클러스터 전역의 _id 필드에 고유성 제약 조건을 적용하지 않습니다.

_id 필드 샤드 키 아닌 경우 고유성 제약 조건은 문서 를 저장하는 샤드 에만 적용됩니다. 즉, 두 개 이상의 문서가 서로 다른 샤드에 있는 경우 동일한 _id 값을 가질 수 있습니다.

예시 를 들어, 두 개의 샤드 A와 B에 걸쳐 있는 샤드 키 {x: 1} 이 있는 샤딩된 컬렉션 생각해 보겠습니다. _id 키는 샤드 키 아니므로 컬렉션 샤드 A에 _id1 을 가진 문서 가질 수 있습니다. 샤드 B에 _id 값이 1 인 다른 문서 있습니다.

_id 필드 샤드 키 아닌 경우, MongoDB 애플리케이션 예시 _id 필드 채우기 위해 고유 식별자를 사용하여 샤드 전체에서 _id 값의 고유성을 보장할 것으로 예상합니다.

고유한 인덱스 제약 조건은 다음을 의미합니다.

  • 샤딩할 컬렉션 의 경우, 컬렉션 여러 개의 고유 인덱스가 있는 경우 샤드 키 모든 고유 인덱스의 접두사가 아닌 이상 컬렉션 샤드 할 수 없습니다.

  • 이미 샤딩된 컬렉션 의 경우, 샤드 키 접두사로 포함되어 있지 않으면 다른 필드에 고유 인덱스를 생성할 수 없습니다.

  • 고유 인덱스 인덱스된 필드 누락된 문서 에 대해 null 값을 저장합니다. 즉, 누락된 인덱스 필드 null 인덱스 키 값의 다른 인스턴스 로 처리됩니다. 자세한 내용은 고유한 단일 필드 인덱스에서 누락된 문서 필드를 참조하세요.

샤드 키 가 아닌 필드 에서 고유성을 유지하려면 임의 필드에 대한 고유 제약 조건을 참조하세요.

MongoDB 5.0부터는 동일한 키 패턴을 가진 고유한 희소 인덱스와 고유한 비희소 인덱스가 단일 컬렉션에 존재할 수 있습니다.

이 예시에서는 동일한 키 패턴과 다른 sparse 옵션을 사용하여 여러 인덱스를 만듭니다.

db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } )
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )

sparse 옵션을 사용하거나 사용하지 않고 동일한 키 패턴으로 기본 인덱스를 생성할 수도 있습니다.

db.scoreHistory.createIndex( { score : 1 }, { name: "sparse_index", sparse: true } )
db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } )

기본 인덱스와 고유 인덱스는 동일한 키 패턴 으로 존재할 수 있습니다.

키 패턴의 이러한 중복은 이미 인덱싱된 필드에 고유 인덱스를 추가할 수 있게 합니다.

이 예시에서는

키 패턴 { score : 1 }으로 기본 인덱스를 생성하고 문서 3개를 삽입합니다.

db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } )
db.scoreHistory.insert( { score : 1 } )
db.scoreHistory.insert( { score : 2 } )
db.scoreHistory.insert( { score : 3 } )

동일한 키 패턴 { score : 1 } 을 사용하여 고유 인덱스를 만듭니다.

db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } )

고유 인덱스로 인해 실패한 중복된 score 문서를 삽입해 보십시오.

db.scoreHistory.insert( { score : 3 } )

돌아가기

데이터 만료

스킬 배지 획득

무료로 '인덱싱 설계 기초'를 마스터하세요!

자세한 내용을 알아보세요.

이 페이지의 내용