programing

MongoDB - 10진수 유형의 값은 어떻습니까?

telebox 2023. 5. 22. 20:56
반응형

MongoDB - 10진수 유형의 값은 어떻습니까?

저는 현재 금융 관련 작은 프로젝트를 위해 MongoDB를 배우고 적용하고 있습니다.


MongoDB in Action을 읽어보면 다음과 같이 나옵니다.

BSON 숫자 유형에서 일반적으로 발생하는 유일한 다른 문제는 십진수 지원의 부족입니다.즉, 통화 값을 MongoDB에 저장하려는 경우 정수 유형을 사용하고 값을 센트 단위로 유지해야 합니다.


저의 금융 관련 상품은 통화 가치가 포함될 것입니다만, 위의 내용에 대해 조금 혼란스럽거나 걱정됩니다.제 질문은 다음과 같습니다.

  1. 사용할 수 있습니까?double그들을 위하여currency values내 프로젝트에서?
  2. 직접 사용할 경우 어떤 일이 발생하거나 결과가 발생합니까?double그들을 위해?
  3. 십진법이 금융상품의 필수품이라면, MongoDB를 사용하는 것은 나쁜 생각입니까?
  4. 무슨 뜻입니까?you need to use an integer type and keep the values in cents그 말은 제가 저장할 것이라는 뜻인가요?1.34 dollars그러면 저장해야 합니다.134 cents?

재정적인 목적으로 정확한 표현을 사용하려면 부분적인 부분에 반올림 오차가 발생하므로 이중 또는 부동 소수점 값이 적합하지 않습니다.특정 십진수 값은 이진 기반 부동 소수점을 사용하여 표시할 수 없으므로 근사해야 합니다.

자세한 내용은 부동 소수점 숫자 반올림 문제를 참조하십시오. 자세한 내용을 보려면 부동 소수점 산술에 대해 모든 컴퓨터 과학자가 알아야 하는 내용을 참조하십시오.

정수 유형(값을 센트 단위로 저장)을 사용하는 것이 잠재적인 반올림 오류를 방지하는 것이 좋습니다.이 접근 방식은 MongoDB 문서에서 화폐 데이터 모델링을 위한 "척도 계수 사용"으로 설명되며 MongoDB 3.2 및 이전 버전에 대한 일반적인 해결 방법입니다.

MongoDB 3.4에는 통화 데이터 필드를 정확하게 조작할 수 있는 새로운 Decimal BSON 유형이 포함되어 있습니다.

MongoDb는 3.4 버전에서 Decimal 데이터 유형에 대한 지원을 추가했습니다.그것은 또한 껍질에서 이용할 수 있습니다.

3.4는 새로운 십진수 데이터 유형으로 십진수 128 형식을 지원합니다.10진수 128 형식은 최대 34자리의 10진수(예: 유의한 숫자)와 -6143 - +6144의 지수 범위를 지원합니다.

십진수 값의 근사치만 저장하는 이중 데이터 유형과 달리 십진수 데이터 유형은 정확한 값을 저장합니다.예를 들어 10진수 10진수("9.99")의 정확한 값은 9.99이고, 9.99를 곱하면 대략적인 값은 9.990000000002131628입니다.

통화를 센트 값으로 저장하지 않으려는 경우 다음과 같은 개체로 1.34달러의 통화를 저장할 수 있습니다.

{
    major: 1,
    minor: 34,
    currency: "USD"
}

이와 같은 물체로 수학을 하는 것은 쉽지 않을 것이고 상업적 반올림 규칙을 사용하지 않을 것입니다.그러나 데이터베이스에서 비즈니스 로직을 수행해서는 안 됩니다. 특히 MongoDB와 같은 "멍청한" 데이터베이스일 때는 더욱 그렇습니다.

이러한 개체를 에서/로 직렬화/직렬화해야 합니다.Money반올림 규칙에 대한 기본 통화 수학 연산을 구현하고 다른 통화 단위로 연산을 수행하려고 할 때 예외를 던지는 응용 프로그램의 클래스($12.34 + 14.95€ = error먼저 환율을 제공하여 한 통화를 다른 통화로 전환해야 합니다.

Mongoose를 사용하는 경우 스키마 정의에서 getter/setter 함수를 사용할 수 있습니다.

function getDecimalNumber(val) {    return (val/1000000); }
function setDecimalNumber(val) {    return (val*1000000); }

다음과 같은 스키마 개체에 적용할 수 있습니다.

balance: { type: Number, default: 0, get: getDecimalNumber, set: setDecimalNumber },

곱셈/나눗셈할 0의 수는 원하는 정확도에 따라 달라집니다.

MongoDB가 마침내 소수점에 대한 지원을 추가한 것처럼 보이지만, 작성 당시에는 개발이 막 끝났지만, 곧 안정적인 버전(3.4?)에서 사용할 수 있기를 바랍니다.

https://jira.mongodb.org/browse/SERVER-1393

이 게시물이 오래된 것은 알지만 구글에서 높은 순위를 차지하고 있기 때문에...

재무 데이터를 저장하는 가장 좋은 솔루션은 MongoDB가 직접 문서화한 정확도를 사용하는 것입니다. 여기서 http://docs.mongodb.org/v2.6/tutorial/model-monetary-data/ #balue-value-value-value-value-value-value-values를 참조하십시오.

{price: 9990, currency: "USD" }

데이터가 필요할 때는 100으로 나누면 됩니다. 두 자리 정밀도를 원한다고 가정하면 됩니다.단점은 항상 같은 정밀도로 작업해야 한다는 것입니다.

NodeJS 사용자:

NodeJS를 사용하는 경우 NumberDecimal(string)을 직접 사용하지 않고 대신 Decimal128.fromString(string)을 사용합니다.

참조:

예:

const Decimal128 = require('mongodb').Decimal128

usersCollection.findOneAndUpdate({_id: ObjectID(this.data.userId), "myWells.wellId": ObjectID(this.data.wellId)},
  { 
    $set: { "myWells.$.interest": Decimal128.fromString(this.data.interest) }
  }
)

언급URL : https://stackoverflow.com/questions/11541939/mongodb-what-about-decimal-type-of-value

반응형