Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 NumberLong(숫자)과 NumberLong("문자열")의 차이점 완벽 정리

MongoDB에서 64비트 정수를 다룰 때 사용하는 NumberLong()은 인자를 어떻게 전달하느냐에 따라 결과가 크게 달라집니다. 숫자 리터럴을 그대로 전달하는 NumberLong(x) 방식은 값이 표현 한계를 넘어 정밀도 손실로 인해 반올림되는 반면, 문자열로 전달하는 NumberLong("x") 방식은 원래 값을 그대로 보존합니다.

왜 이런 차이가 발생할까요?

mongo 셸은 자바스크립트 기반으로 동작하며, 자바스크립트의 숫자는 IEEE 754 배정밀도 부동소수점 방식으로 표현됩니다. 이 방식은 2의 53제곱(약 9,007조)을 초과하는 정수를 정확하게 표현할 수 없습니다. 따라서 숫자 리터럴로 전달된 값은 이미 셸 단계에서 정밀도가 손실된 상태가 됩니다. 반면 문자열로 전달하면 MongoDB가 해당 문자열을 직접 64비트 정수로 변환하므로 정확한 값이 유지됩니다.

예제로 확인하기

두 가지 방식을 비교하기 위해 컬렉션에 문서를 삽입해 보겠습니다.

> db.demo603.insert({"longValue" : NumberLong(988998985857575789)});
WriteResult({ "nInserted" : 1 })
> db.demo603.insert({"longValueInString" : NumberLong("988998985857575789")});

이제 find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.

> db.demo603.find().pretty();

위 명령을 실행하면 다음과 같은 결과가 출력됩니다.

{
    "_id" : ObjectId("5e9605e5ed011c280a0905d1"),
    "longValue" : NumberLong("988998985857575808")
}
{
    "_id" : ObjectId("5e9605faed011c280a0905d2"),
    "longValueInString" : NumberLong("988998985857575789")
}

결과 분석

출력 결과를 자세히 살펴보면 차이가 명확합니다. 숫자 리터럴로 전달한 longValue 필드는 원래 입력한 988998985857575789가 아니라 988998985857575808로 저장되었습니다. 이는 정밀도 손실로 인해 값이 반올림된 것입니다. 반면 문자열로 전달한 longValueInString 필드는 988998985857575789로 원래 값이 정확하게 그대로 저장되었습니다.

결론

2의 53제곱을 초과하는 큰 정수 값을 MongoDB에 저장할 때는 반드시 NumberLong("값")처럼 문자열 형태로 전달해야 합니다. 그렇지 않으면 의도하지 않은 값이 저장되어 데이터 정합성 문제가 발생할 수 있습니다.