Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Деньги: INT(BIGINT) vs DECIMAL(n,2) / 8 сообщений из 8, страница 1 из 1
23.10.2008, 12:50
    #35611476
Semen Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Деньги: INT(BIGINT) vs DECIMAL(n,2)
Здравствуйте!

Известно, что вещественные типы с плавающей запятой FLOAT, REAL, DOUBLE не подходят(или, можно сказать, не очень удобны) для хранения денег. Часто слышу, что деньги лучше хранить в копейках (целый тип) или в типе DECIMAL(n,2). А какой вариант лучше? В каких случаях есть преимущества(недостаток) первого варианта перед вторым? Какие условия задачи надо учитывать при выборе того или другого варианта?

Заранее благодарен
С уважением, Семен Попов
...
Рейтинг: 0 / 0
23.10.2008, 13:26
    #35611654
BuryCommoner
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Деньги: INT(BIGINT) vs DECIMAL(n,2)
Принципиальной разницы нет. С BIGINT придётся делить/умножать при операциях записи/вывода.
...
Рейтинг: 0 / 0
23.10.2008, 14:18
    #35611892
Semen Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Деньги: INT(BIGINT) vs DECIMAL(n,2)
BuryCommonerПринципиальной разницы нет. С BIGINT придётся делить/умножать при операциях записи/вывода.Да, в приложении с копейками нам придется дополнительно делать обработку ввода/вывода, так же и при разных расчетах с деньгами, а это дополнительные телодвижения, операции. Но многие прогеры, особенно явисты, больше склоняются именно к копейкам. Почему так?
...
Рейтинг: 0 / 0
23.10.2008, 14:43
    #35612001
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Деньги: INT(BIGINT) vs DECIMAL(n,2)
ЗдравствуйтеSemen PopovИзвестно, что вещественные типы с плавающей запятой FLOAT, REAL, DOUBLE не подходят(или, можно сказать, не очень удобны) для хранения денег. Часто слышу, что деньги лучше хранить в копейках (целый тип) или в типе DECIMAL(n,2). А какой вариант лучше? В каких случаях есть преимущества(недостаток) первого варианта перед вторым? Какие условия задачи надо учитывать при выборе того или другого варианта?Иногда требуется хранить деньги с достаточно большим кол-вом знаков после запятой - для большей точности расчетов.
И тогда может сыграть большее кол-во значащих цифр у decimal (31 против 19).
В v9.5 есть ещё более удобный тип decfloat.
...
Рейтинг: 0 / 0
23.10.2008, 15:16
    #35612170
Semen Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Деньги: INT(BIGINT) vs DECIMAL(n,2)
Mark BarinsteinИногда требуется хранить деньги с достаточно большим кол-вом знаков после запятой - для большей точности расчетов.
И тогда может сыграть большее кол-во значащих цифр у decimal (31 против 19).
В v9.5 есть ещё более удобный тип decfloat.Спасибо. Но, не представляю, как организуется логика на уровне базы для хранения дробных копеек, используя только целочисленные типы. Мне кажется, это уже усложнение. Скорее, целочисленный тип для хранения денег используется в простых задачах, где требуется хранить только деньги (реальную сумму), а не всякие там проценты, пени и т.п., которые должны иметь точность более двух знаков после запятой. Если необходимо, рассчёты этих процентов, пени и т.п. можно вынести на уровень приложения, когда это не столь часто используется. В приложении с более сложной логикой (например, в банковских приложениях) было бы логично использовать тип DECIMAL.
У меня простая задача. Хранить по людям их денежные затраты. Получать из приложения отчёт о суммарных затратах. Есть ещё НДС, но он нужен только для отчёта, поэтому эти расчёты можно вынести(?) в приложение. Хотя там тоже могу встретить проблемы с вещественными типами данных и операциями над ними.
...
Рейтинг: 0 / 0
24.10.2008, 07:55
    #35613539
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Деньги: INT(BIGINT) vs DECIMAL(n,2)
Допустим, вы считаете, что (запрос 1)
Код: plaintext
1.
2.
SELECT SUM(integer_field)/ 100 . 00 
FROM ...
значительно быстрее на ваших данных, чем (запрос 2)
Код: plaintext
1.
2.
SELECT SUM(decimal_field)
FROM ...
(разумно убедиться, действительно ли это так).

Тогда вы можете, например
1) создать таблицу (назову T) c integer_field
2) создать над этой таблицей view (назову V) с integer_field/100.00 as decimal field
3) делаете для V триггера INSTEAD OF, производящие нужные манипуляции над T

Теперь вы можете удобно пользоваться V для небольших количеств данных (например, ручного ввода) и T для суммирования больших количеств.

В любом случае, "FLOAT, REAL, DOUBLE" имеют проблемы с представлением и округлением копеек и потому для денег не годятся.
...
Рейтинг: 0 / 0
24.10.2008, 08:35
    #35613579
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Деньги: INT(BIGINT) vs DECIMAL(n,2)
Для произвольного количества знаков после запятой (integer_scale IN (1,10,100,1000...)):

Код: plaintext
1.
2.
3.
CREATE VIEW V AS
SELECT CAST(integer_value AS DECIMAL(...))/integer_scale AS decimal_value, 
...
(правда, в отличие от предыдущего случая, приложение уже обязано знать про integer_scale)

Суммирование; группируем дважды, чтобы уменьшить до минимума количество делений и сложений decimal.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
WITH 
  x(sum_i, scale_i) AS (
    SELECT SUM(integer_value), integer_scale
    FROM T
    GROUP BY integer_scale
  )
SELECT SUM(CAST(sum_i AS DECIMAL(...))/integer_scale)
...

Полагаю, что само по себе суммирование для целых должно быть значительно быстрее, чем decimal (особенно в 64-хбитных системах), но доля времени на чтение с диска может оказаться настолько велика, что овчинка окажется не стоящей выделки. Поэтому для каждого конкретного случая нужно обдумывание и тестирование (конкретных данных на конкретной системе).
...
Рейтинг: 0 / 0
24.10.2008, 09:16
    #35613637
Semen Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Деньги: INT(BIGINT) vs DECIMAL(n,2)
Victor Metelitsa...
Тогда вы можете, например
1) создать таблицу (назову T) c integer_field
2) создать над этой таблицей view (назову V) с integer_field/100.00 as decimal field
3) делаете для V триггера INSTEAD OF, производящие нужные манипуляции над T
...Вот и решение. Я всё не мог додуматься, как организовать на уровне базы функционал обработки ввода/вывода копеек и различных рассчётов с ними. Спасибо.
Victor Metelitsa...
Полагаю, что само по себе суммирование для целых должно быть значительно быстрее, чем decimal (особенно в 64-хбитных системах), но доля времени на чтение с диска может оказаться настолько велика, что овчинка окажется не стоящей выделки. Поэтому для каждого конкретного случая нужно обдумывание и тестирование (конкретных данных на конкретной системе).Да, одной из причин моего перевеса в сторону целых копеек было то, что операции с целочисленными значениями выполняются быстрее. Но тут, как Вы сказали, надо учитывать и другие факторы. Будем тестировать, работать.
...
Рейтинг: 0 / 0
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Деньги: INT(BIGINT) vs DECIMAL(n,2) / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]