Мне любопытно, есть ли реальная разница между money
типом данных и чем-то вроде этого decimal(19,4)
(я полагаю, это то, что деньги используют внутри страны).
Я знаю, что money
это специфично для SQL Server. Я хочу знать, есть ли веская причина выбрать одно из другого; большинство примеров SQL Server (например, база данных AdventureWorks) используют, money
а не decimal
для таких вещей, как информация о ценах.
Должен ли я просто продолжать использовать тип данных money, или вместо него есть преимущество использования десятичного числа? Деньги вводят меньше символов, но это не веская причина :)
sql-server
types
Уэйн Молина
источник
источник
DECIMAL(19, 4)
популярный выбор, проверьте это, также проверьте здесь Форматы Мировой валюты, чтобы решить, сколько десятичных знаков использовать, надеюсь, поможет.Ответы:
Никогда не стоит использовать деньги. Это не точно, и это чистый мусор; всегда используйте десятичную / числовую.
Запустите это, чтобы увидеть, что я имею в виду:
Выход: 2949.0000 2949.8525
Некоторым из людей, которые сказали, что вы не делите деньги на деньги:
Вот один из моих запросов для расчета корреляций, и изменение его на деньги дает неверные результаты.
источник
money
над вmoney
стороне, это «иллюстрация» манипулятивные. Это задокументированный факт, которыйmoney
имеет фиксированную и очень ограниченную точность. В таких случаях нужно сначала умножить, а затем разделить. Измените порядок операторов в этом примере, и вы получите идентичные результаты. Поmoney
сути, это 64-битное целое, и если бы вы имели дело с целыми числами, вы бы умножили перед делением.SQLMenace говорит, что деньги неточны. Но вы не умножаете / делите деньги на деньги! Сколько стоит 3 доллара 50 центов? 150 долларовых центов? Вы умножаете / делите деньги на скаляры, которые должны быть десятичными.
Результаты в правильном результате:
money
Это хорошо, если вам не нужно больше 4 десятичных цифр, и вы убедитесь, что ваши скаляры - которые не представляют деньги -decimal
s.источник
money / money
? Ответ - целые единицы без знака доллара, и это правильно! Это вполне разумный сценарий, предполагающий, что из-за странных крайних случаев, подобных этому,money
это не очень хороший тип данных для использования, поскольку результат всегда обрезается до соответствия,money
а не по обычным правилам точности и масштаба. Что если вы хотите рассчитать стандартное отклонение набораmoney
значений? Да,Sqrt(Sum(money * money))
(упрощенно) действительно имеет смысл.Все опасно, если вы не знаете, что делаете
Даже высокоточные десятичные типы не могут спасти день:
1.000000 <- должно быть 0.6000000
Эти
money
типы являются целыми числамиТекстовые представления
smallmoney
иdecimal(10,4)
могут выглядеть одинаково, но это не делает их взаимозаменяемыми. Вы съеживаетесь, когда видите даты, сохраненные какvarchar(10)
? Это то же самое.За кулисами,
money
/smallmoney
являются простоbigint
/int
Десятичной точкой в текстовом представленииmoney
является визуальный пух, точно так же, как тире в дате гггг-мм-дд. SQL на самом деле не хранит их внутри.Что касается
decimal
противmoney
, выберите все, что подходит для ваших нужд. Этиmoney
типы существуют , так как хранение значений , как что составляет целых кратных 1 / 10000th блока является очень распространенным. Кроме того, если вы имеете дело с реальными деньгами и вычислениями, помимо простого сложения и вычитания, вам не следует делать это на уровне базы данных! Сделайте это на уровне приложения с помощью библиотеки, которая поддерживает округление Банкира (IEEE 754)источник
Я понимаю, что WayneM заявил, что он знает, что деньги специфичны для SQL Server. Тем не менее, он спрашивает, есть ли какие-либо причины использовать деньги сверх десятичной или наоборот, и я думаю, что еще нужно указать одну очевидную причину, а именно использование десятичной дроби означает, что беспокоиться о том, стоит ли вам когда-либо менять свою СУБД, - это еще один повод для беспокойства. - что может случиться.
Сделайте ваши системы максимально гибкими!
источник
date
типа, я бы сказал, что у вас всегда будут такие проблемы. Вы должны сказать: «Не используйте устаревшие типы, когда база данных уже предоставляет более совершенные, более совместимые со стандартами типы и предупреждает об устаревших».Ну, мне нравится
MONEY
! Это на байт дешевле чемDECIMAL
, и вычисления выполняются быстрее, потому что (под прикрытием) операции сложения и вычитания по существу являются целочисленными операциями. Пример @ SQLMenace, который является отличным предупреждением для незнающих, может в равной степени быть применен кINT
egers, где результат будет нулевым. Но это не причина не использовать целые числа - где это уместно .Таким образом, это совершенно «безопасно» и уместно использовать,
MONEY
когда вы имеете дело с тем, с чем вы имеете дело,MONEY
и использовать его в соответствии с математическими правилами, которым оно следует (так же, какINT
eger).Было бы лучше, если бы SQL Server способствовал делению и умножению
MONEY
s наDECIMAL
s (илиFLOAT
s?) - возможно, но они не решили делать это; и при этом они не решили продвигатьINT
егеров кFLOAT
s, разделяя их.MONEY
не имеет проблем с точностью; чтоDECIMAL
добудет иметь больший промежуточный тип , используемый при расчетах просто «функция» с использованием этого типа (и я на самом деле не знаю , как далеко , что «функция» распространяется).Чтобы ответить на конкретный вопрос, «веская причина»? Ну, если вы хотите абсолютную максимальную производительность в
SUM(x)
гдеx
может быть либо,DECIMAL
либоMONEY
, тоMONEY
будет иметь преимущество.Кроме того, не забывайте, что это двоюродный брат меньшего размера -
SMALLMONEY
всего 4 байта, но он имеет максимальный размер214,748.3647
- который довольно мал для денег - и поэтому не всегда подходит.Чтобы доказать смысл использования больших промежуточных типов, если вы явно присваиваете промежуточное значение переменной,
DECIMAL
возникает та же проблема:Производит
2950.0000
(хорошо, так по крайней мереDECIMAL
округлено, а неMONEY
усечено - так же, как целое число).источник
MONEY
на один байт меньше большогоDECIMAL
, с точностью до 19 цифр. Тем не менее, большинство реальных денежных расчетов (до 9,99 млн. Долл. США) могут уместиться в aDECIMAL(9, 2)
, который требует всего пять байтов. Вы можете сохранить размер, меньше беспокоиться об ошибках округления и сделать свой код более переносимым.Мы только что столкнулись с очень похожей проблемой, и теперь я очень +1 за то, что никогда не использую деньги, кроме как в презентации на высшем уровне. У нас есть несколько таблиц (фактически, ваучер продаж и счет-фактура продаж), каждая из которых содержит одно или несколько полей «Деньги» по историческим причинам, и нам необходимо выполнить пропорциональный расчет, чтобы определить, какая часть общего налога на счет-фактуру относится к каждому линия на ваучер продаж. Наш расчет
Это приводит к реальному расчету денег / денег, который вызывает ошибки масштаба в части деления, которая затем умножается до неправильной пропорции НДС. Когда эти значения впоследствии добавляются, мы получаем сумму пропорций НДС, которые не суммируются с общей стоимостью счета. Если бы любое из значений в скобках было десятичным (я собираюсь привести одно из них как таковое), пропорция НДС была бы правильной.
Когда скобки изначально отсутствовали, это работало, я думаю, из-за больших значений, это эффективно имитировало более высокую шкалу. Мы добавили скобки, потому что сначала выполнялось умножение, которое в некоторых редких случаях сказывалось на точности, доступной для вычисления, но теперь это стало причиной гораздо более распространенной ошибки.
источник
В качестве контрапункта общей направленности других ответов. Смотрите много преимуществ денег ... Тип данных! в руководстве SQLCAT по реляционному движку
В частности, я бы отметил следующее
Таким образом, ответ на вопрос «это зависит». Вы должны быть более осторожными с некоторыми арифметическими операциями, чтобы сохранить точность, но вы можете обнаружить, что соображения производительности делают это стоящим.
источник
Я хочу дать другое представление о ДЕНЬГАХ и NUMERICAL, в значительной степени основываясь на своем собственном опыте и опыте ... Моя точка зрения здесь - ДЕНЬГИ, потому что я работал с ним в течение длительного времени и никогда не использовал NUMERICAL. ,
ДЕНЬГИ Pro:
Родной тип данных . Он использует собственный тип данных ( целое число ), такой же, как регистр ЦП (32 или 64 бита), поэтому для вычисления не нужны лишние издержки, поэтому он меньше и быстрее ... MONEY требуется 8 байтов и NUMERICAL (19, 4 ) требуется 9 байт (на 12,5% больше) ...
ДЕНЬГИ быстрее, если их использовать, как предполагалось (как деньги). Как быстро? Мой простой
SUM
тест на 1 млн. Данных показывает, что ДЕНЬГИ составляют 275 мс, а ЧИСЛЕННЫЕ 517 мс ... Это почти вдвое быстрее ... Почему тест СУММ? Смотрите следующую Pro точкуДЕНЬГИ Con:
money
же, не нужно быть таким точным, и их следует использовать в качестве денег, а не просто число...Но ... Большой, но здесь даже ваше приложение связано с реальными деньгами, но не используйте его во многих операциях SUM, например, в бухгалтерском учете. Если вместо этого вы используете множество делений и умножений, вам не следует использовать ДЕНЬГИ ...
источник
money
столбцеВсе предыдущие посты приносят действительные баллы, но некоторые не дают точного ответа на вопрос.
Вопрос в том, почему кто-то предпочитает деньги, если мы уже знаем, что это менее точный тип данных и может привести к ошибкам при использовании в сложных вычислениях?
Вы используете деньги, когда не будете делать сложные вычисления и можете обменять эту точность на другие нужды.
Например, когда вам не нужно делать эти вычисления, и вам нужно импортировать данные из допустимых текстовых строк валюты. Это автоматическое преобразование работает только с типом данных MONEY:
Я знаю, что вы можете сделать свою собственную процедуру импорта. Но иногда вы не хотите воссоздавать подпрограмму импорта со специфическими для мира форматами локали.
Другой пример, когда вам не нужно делать эти вычисления (вам нужно просто сохранить значение) и вам нужно сохранить 1 байт (деньги занимают 8 байт, а десятичное число (19,4) - 9 байт). В некоторых приложениях (быстрый процессор, большой объем оперативной памяти, медленный ввод-вывод), например, просто чтение огромного количества данных, это также может быть быстрее.
источник
Вы не должны использовать деньги, когда вам нужно сделать умножения / деления на значение. Деньги хранятся так же, как целое число, тогда как десятичная дробь хранится в виде десятичной точки и десятичных цифр. Это означает, что в большинстве случаев деньги будут снижать точность, тогда как десятичная дробь будет делать это только при преобразовании обратно в исходный масштаб. Деньги - это фиксированная точка, поэтому ее масштаб не изменяется при расчетах. Однако, поскольку это фиксированная точка, когда она печатается в виде десятичной строки (в отличие от фиксированной позиции в строке с основанием 2), значения до масштаба 4 представляются точно. Таким образом, для сложения и вычитания деньги в порядке.
Десятичная дробь представлена в основании 10 внутренне, и, таким образом, положение десятичной точки также основано на числе 10. Что делает его дробную часть точно отражающей его стоимость, точно так же как с деньгами. Разница в том, что промежуточные значения десятичной дроби могут поддерживать точность до 38 цифр.
Для числа с плавающей запятой значение сохраняется в двоичном виде, как если бы оно было целым числом, а позиция десятичной (или двоичной, ага) точки относительно битов, представляющих число. Поскольку это двоичная десятичная точка, базовые числа 10 теряют точность сразу после десятичной точки. 1/5 или 0,2 не могут быть представлены именно таким образом. Ни деньги, ни десятичные числа не страдают от этого ограничения.
Достаточно просто преобразовать деньги в десятичную, выполнить вычисления, а затем сохранить полученное значение обратно в денежное поле или переменную.
От моего POV я хочу, чтобы вещи, которые случаются с числами, просто происходили без необходимости слишком много думать о них. Если все вычисления будут преобразованы в десятичную, то для меня я бы просто хотел использовать десятичную. Я бы сохранил поле денег для отображения.
По размерам я не вижу достаточной разницы, чтобы передумать. Деньги занимают 4 - 8 байтов, тогда как десятичные могут быть 5, 9, 13 и 17. 9 байтов могут охватывать весь диапазон, который могут 8 байтов денег. По индексу (сравнение и поиск должны быть сопоставимы).
источник
Я нашел причину использования десятичной над деньгами в точности предмета.
DecimalResult> 1.000000
MoneyResult> 0,9999
FloatResult> 1
Просто проверьте это и примите решение.
источник
Я только что увидел эту запись в блоге: Деньги против десятичного в SQL Server .
Который в основном говорит, что у денег есть проблема точности ...
Для
money
типа вы получите 19,30 вместо 19,34. Я не уверен, существует ли сценарий приложения, который делит деньги на 1000 частей для расчета, но этот пример действительно имеет некоторые ограничения.источник
money
и »smallmoney
с точностью до десятитысячной доли денежных единиц, которые они представляют». как сказано в msdn.microsoft.com/en-us/library/ms179882.aspx, поэтому любой, кто говорит «это мусор», не знает, о чем говорит.