MongoDB에서 고유(unique) 제약 조건을 적용하는 방법


이번에는 “MongoDB에서 고유(unique) 제약 조건을 적용하는 방법"에 대해 알아보자.

고유(unique) 제약 조건 적용

MongoDB에서 고유(unique) 제약 조건을 적용하려면 인덱스를 생성할 때 createIndex()의 옵션으로 uniquetrue를 지정하면 된다.

아래에서는 “단일 키 인덱스"의 경우와 “복합 키 인덱스"의 경우에 대해 예제 코드를 살펴 보겠다.

단일 키 인덱스

단일 키 인덱스라면 단순히 다음과 같은 코드를 mongo 쉘에서 실행하면 생성할 수 있다.

> db.members.createIndex({ userId: 1 }, { unique: true })

복합 키 인덱스

복합 키 인덱스의 경우에도 단일 키 인덱스와 코드는 변하지 않는다.

> db.members.createIndex({ firstname: 1, lastname: 1 }, { unique: true })

복합 키 인덱스의 경우, 복합 키의 조합으로 유일하기만 하면 되기 때문에, 아래에서는 문제 없게 설정할 수 있다.

> db.members.insert({ firstname: "kc", lastname: "Kim" })
> db.members.insert({ firstname: "et", lastname: "Kim" })
> db.members.insert({ firstname: "kc" })

고유(unique) 제약 조건의 설정 제한

RDB의 경우와 비슷하지만, 이미 중복 데이터가 등록된 컬렉션에 대해서 고유 제약 조건을 걸 수는 없다. 이미 중복되어 버린 상태에서는 당연하다고 하면 당연할 수 있겠지만…

또, 해시 인덱스에 대해서 고유 제약 조건을 설정하는 것은 추천 되지 않는다. (Hashed Indexes의 Considerations)

고유 제약 조건 키에 값이 설정되지 않은 경우의 동작

위에서 “복합 키 인덱스"로 고유 제약 조건을 설정한 패턴의 데이터 등록 예제에서 처럼 값이 없는 필드가 존재하는 경우에는 내부적으로는 null이 지정된 것으로 처리된다.

예를 들어, 다음과 같이 필드 x에 대한 고유 제약 조건이 있는 콜렉션이 있다고 할 때

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

필드 x를 지정하지 않는 데이터를 등록되었다고 가정한다.

> db.collection.insert({ y: 1 })
WriteResult({ "nInserted" : 1 })

처음에는 x: null으로 지정되므로 성공적으로 등록할 수 있다. 계속해서 필드 x가 존재하지 않는 다른 데이터를 삽입하면 어떻게 될까?

> db.collection.insert({ z: 1 })
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "E11000 duplicate key error collection: test.collection index: x_1 dup key: { : null }"
    }
})

위에 같이 오류가 발생하여 삽입할 수 없음을 알 수 있다. 또, 에러 메세지로부터도 지정이 없으면 null이 지정된다는 것을 알 수 있다.

참고 문서