Подтвердить что ты не робот

MongoDB - Как насчет десятичного значения?

В настоящее время я изучаю и применяю MongoDB для небольшого финансового проекта.


Когда я читаю MongoDB в действии, он говорит:

Единственная проблема, которая обычно возникает с числовыми типами BSON, - это отсутствие десятичной поддержки. Это означает, что если вы планируете сохраняя значения валюты в MongoDB, вам нужно использовать целочисленный тип и сохранить значения в центах.


Мой финансовый продукт будет включать в себя некоторые валютные ценности, но я немного смущен или обеспокоен вышеуказанным выражением. Вот мои вопросы:

  • Могу ли я использовать double для этих currency values в моем проекте?
  • Что произойдет или будут последствия, если я использую для них double для них?
  • Если десятичный тип является обязательным для финансового продукта, это плохая идея использовать MongoDB?
  • Что значит you need to use an integer type and keep the values in cents? Означает ли это, что если я собираюсь хранить 1.34 dollars, тогда я должен хранить 134 cents?

Спасибо

4b9b3361

Ответ 1

Если вы хотите получить точное представление для финансовых целей, то значения удвоения или значения с плавающей запятой неприемлемы, поскольку дробные части подвержены ошибкам округления. Определенные десятичные значения не могут быть представлены с использованием двоичных плавающих точек и должны быть аппроксимированы.

Для менее технического введения см. Проблема с округлением чисел с плавающей запятой; если вы хотите выкрикнуть, тогда прочитайте Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой.

Рекомендация использования целочисленного типа (сохранение значения в центах) заключается в том, чтобы избежать возможных ошибок округления. Этот подход описывается как " Использование коэффициента масштабирования" в документации MongoDB для моделирование денежных данных и является общим обходным моментом для MongoDB 3.2 и ранее.

MongoDB 3.4 включает новый Decimal BSON type, который обеспечивает точную точность для манипулирования полями денежных данных.

Ответ 2

Если вы не хотите хранить валюту в виде центов, вы можете хранить валюту в размере 1,34 доллара США в качестве объекта, подобного этому:

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

Выполнение любой математики с такими объектами было бы непросто и не использовало бы правила коммерческого округления. Но в любом случае вы не должны делать какую-либо бизнес-логику в базе данных, особенно если это "тупая" база данных, например MongoDB.

Что вы должны делать, это сериализовать/десериализовать эти объекты из/в класс Money в вашем приложении, который реализует основные операции математической математики в отношении правил округления и генерирует исключение, когда вы пытаетесь выполнить операцию с другой валютой единицы ($12.34 + 14.95€ = error - сначала конвертировать одну валюту в другую валюту, предоставляя обменный курс).

Ответ 3

Если вы используете Mongoose, вы можете использовать функции getter/setter в определении схемы, например.

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

Применимо к объекту схемы, например

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

Количество нулей для умножения/деления зависит от требуемой точности.

Ответ 4

Похоже, что MongoDB наконец-то добавила поддержку десятичных знаков, хотя на момент написания это только что закончилась, но, надеюсь, она должна быть доступна очень скоро в стабильной версии (3.4?).

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

Ответ 5

Я знаю, что этот пост старый, но он высоко оценивает Google, поэтому...

Лучшим решением для хранения финансовых данных является точная точность, как это описано самими MongoDB здесь http://docs.mongodb.org/v2.6/tutorial/model-monetary-data/#monetary-value-exact-precision.

{price: 9990, currency: "USD" }

И когда вам нужны данные, просто разделите их на 100, считая, что вам нужна двузначная точность. Недостатком является то, что вам всегда нужно работать с одинаковой точностью.

Ответ 6

MongoDb добавил поддержку десятичный тип данных в версии 3.4. Он также доступен из shell.

3.4 добавляет поддержку формата decimal128 с новым десятичным типом данных. Формат decimal128 поддерживает номера до 34 десятичных знаков цифры (то есть значащие цифры) и диапазон экспоненциального диапазона от -6143 до +6144.

В отличие от двойного типа данных, в котором сохраняется только аппроксимация десятичные значения, тип десятичных данных сохраняет точное значение. Для Например, десятичный NumberDecimal ( "9.99" ) имеет точное значение 9.99 где в качестве двойного 9.99 будет иметь приблизительное значение 9,9900000000000002131628...