MongoDB를 사용하면서 ObjectId 타입을 접하게 되었습니다.
저는 ObejctId에 대해서 MongoDB의 Document를 식별하기 위해 사용되는 12바이트의 식별자라고만 인지하고 있었습니다.
그런데 저희 팀의 사수님께서 'ObjectId가 생성될 때 프로세스 ID 값도 사용된다'는 말씀을 해주셨습니다.
단순히 랜덤숫자와 생성날짜의 조합이 아닌 프로세스의 ID값이 생성될 때 영향을 미친다?
저는 ObjectId가 생성될 때 영향을 주는 다른 값들도 존재하는지,
그리고 존재한다면 어떤 것들이 있는지 궁금해져 이 글을 작성하게 되었습니다.
1. MongoDB와 BSON
먼저, MongoDB는 BSON을 사용하고 있습니다.
또한 NoSQL 데이터베이스로 문서 기반(Document-Oriented) 저장 방식을 사용합니다.
BSON 과 JSON 의 차이점
- BSON
BSON은 'Binary JSON' 의 줄임말로 JSON과 비슷하지만 이진(Binary) 포맷입니다.
BSON은 컴퓨터가 읽기 쉬운 포맷이라 저장과 전송 속도가 더 빠릅니다.
- JSON
사람이 읽기 쉬운 텍스트 포맷이라 주로 데이터를 주고받을 때 사용됩니다.
특징 | JSON | BSON |
형식 | 사람이 읽을 수 있는 텍스트 | 컴퓨터가 읽기 쉬운 이진(Binary) |
데이터 크기 | 상대적으로 더 큼 | 상대적으로 더 작음 |
지원 데이터 타입 | 기본 타입 (문자열, 숫자, 배열 등)만 지원 | ObjectId, Date, Binary 등 확장 타입 지원 |
속도비교 | 저장/처리 속도가 상대적으로 느림 | 상대적으로 빠름 |
MongoDB는 왜 BSON 을 사용할까?
⓵ 효율성
- BSON은 이진 데이터 포맷으로 데이터를 더 적은 공간에 저장하고 더 빠르게 처리할 수 있습니다.
⓶ 유연한 데이터 타입
- BSON은 JSON보다 많은 데이터 타입을 지원합니다. (예 : ObjectId, Date, Decimal128, Binary Data 등)
- 이는 MongoDB가 다양한 데이터 구조를 저장할 수 있도록 도와줍니다.
⓷ 인덱싱 및 쿼리 최적화
- BSON은 데이터 길이와 타입 정보를 포함하므로 MongoDB가 데이터를 인덱싱하고 쿼리를 최적화하는 데 도움을 줍니다.
RDB에서는 왜 BSON을 안쓸까?
⓵ 고정된 스키마
- RDB는 데이터를 고정된 스키마를 사용하기 때문에 BSON이 필요 없는 구조입니다.
- RDB는 정형화된 데이터를 저장하고 관계를 관리하는 데 중점을 두는 반면에 BSON은 반정형 데이터(유연한 문서 구조)를 저장하기 위해 만들어졌습니다.
2. ObjectId란?
BSON을 위에서 언급한 이유는
ObjectId가 BSON에서 지원하는 데이터 타입 중 하나이기 때문입니다.
BSON의 데이터 타입인 ObjectId
- BSON은 JSON보다 확장된 데이터 타입을 지원하며 그 중 하나가 바로 ObjectId입니다.
- JSON에서는 고유 식별자를 단순 문자열로 저장하지만 BSON에서는 ObjectId를 고유 식별자 타입으로 저장하며 이는 12바이트 이진 데이터로 효율적으로 처리됩니다.
BSON의 효율성을 극대화한 데이터 타입
- ObjectId는 BSON 포맷으로 저장될 때 일반 문자열보다 크기가 작고 생성과 비교가 빨라 쿼리 성능 최적화에도 기여합니다.
ObjectId의 구조?
(참고 : 1바이트 = 2개의 16진수 문자)
3. ObjectId와 UUID 차이점
ObjectId와 UUID의 차이점을 비교해보겠습니다.
ObjectId vs UUID
특징 | ObjectId (MongoDB 사용 기준 설명) | UUID |
크기 | 12바이트 | 16바이트 |
구조 | 위 그림 참고 | 랜덤 데이터 또는 시간 + 네트워크 정보 기반 |
생성규칙 | MongoDB 내부에서 자동 생성 | RFC 4122 표준에 따라 생성 |
시간정보 포함 여부 | 생성된 시점의 타임스탬프 기록함 | 일반적으로 포함되지 않음 (버전따라 다름) |
고유성 보장 방법 | 타임스탬프 + 머신 ID + 프로세스 ID로 충돌 방지 | 전 세계적으로 고유한 값 생성 |
읽기/쓰기 성능 비교 | BSON 기반으로 UUID보다 크기가 작아 더 빠르게 처리 가능 | ObjectId보다 크기가 커서 처리 속도가 다소 느림 |
4. ObjectId 중복가능성
크기 비교 부분을 적다가 문득 'UUID는 16바이트이고, ObjectId는 12바이트이니, 이론적으로 ObjectId가 UUID보다 중복 가능성이 더 높지 않을까?'라는 생각을 하게 되었습니다.
실제로 이론적으로는 UUID가 ObjectId보다 중복 가능성이 낮다는 점은 맞습니다.
그렇지만 ObjectId 또한 UUID만큼의 고유성을 보장합니다.
그래서 고유성 보장을 하는가?
MongoDB는 단일 클러스터 내에서 여러 서버와 프로세스가 동시에 데이터를 처리할 수 있도록 설계되어 있습니다. 이를 위해 ObjectId는 분산 환경에서의 고유성을 보장하는 구조를 가지고 있습니다.
- 타임스탬프 : 동일한 시간에 생성된 ObjectId를 구별합니다.
- 머신 ID : 각 서버에서 생성되는 ObjectId가 서로 다르게 하여, 서버 간 충돌을 방지합니다.
- 프로세스 ID : 같은 서버에서 실행되는 여러 프로세스 간 충돌을 방지합니다.
- 카운터 : 같은 타임스탬프, 머신, 프로세스에서 생성된 ObjectId의 중복을 방지합니다.
이렇게 설계된 ObjectId는 분산 시스템에서 데이터가 여러 서버와 샤드(shard)로 분산되어 저장될 때에도
각 서버에서 고유한 ID를 생성할 수 있도록 보장합니다.
따라서 MongoDB의 분산 환경에서 ObjectId는 충돌 가능성이 거의 없으며 클러스터 전체에서 충분히 고유성을 유지할 수 있습니다.
중복 가능성 관점에서는 UUID가 더 우수하지만 MongoDB의 분산 환경에서는 ObjectId만으로도 충분한 고유성을 제공합니다.
[출처]
https://www.mongodb.com/ko-kr/docs/manual/reference/method/ObjectId/
'데이터베이스 > Mongo' 카테고리의 다른 글
[Mongo] MongoDB 설치 및 간단한 테스트 진행 (+에러해결) (0) | 2024.04.09 |
---|