Числовые против реальных типов данных для хранения денежных значений - PullRequest
0 голосов
/ 09 мая 2018

Ответ на вопрос о хорошей схеме для биржевых данных рекомендовал эту схему:

 Symbol -  char 6
 Date -  date
 Time -  time
 Open -  decimal 18, 4
 High -  decimal 18, 4
 Low -  decimal 18, 4
 Close -  decimal 18, 4
 Volume -  int

Кроме того, в документации Postgres сказано:

"Если вам требуется точное хранение и вычисления (например, для денежных сумм), используйте вместо этого числовой тип (типов с плавающей запятой)."

Я довольно новичок в SQL, и я надеюсь, что это не очень наивный вопрос. Меня интересует необходимость использования числового типа данных (особенно 18,4) - мне кажется, это излишне. И «точное» не совсем то, что я бы указал, если точное означает исправить до 12 десятичных знаков.

Я думаю об использовании реальных 10,2 для денежных столбцов. Вот мое обоснование.

Типичный расчет может сравнить цену акций (2 знака после запятой) со скользящей средней (которая может иметь много знаков после запятой), чтобы определить, какая из них больше. Насколько я понимаю, отображаемое значение среднего (и любых вычисленных результатов) будет округлено до 2 десятичных знаков, но эти вычисления будут выполняться с использованием более высокой точности сохраненного внутреннего числа.

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

Я здесь далеко от базы, и возможно ли получить неправильный ответ на приведенное выше сравнение, используя реальный тип данных 10,2?

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

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Давайте начнем со схемы выше и посмотрим, как 18,4 будет выглядеть в числах с плавающей запятой:

select '12345678901234.5678'::float4;
  float4    
-------------
 1.23457e+13
(1 row)

select '12345678901234.5678'::double precision;
  float8      
------------------
 12345678901234.6
(1 row)

Поэтому 14 чисел (до десятичной запятой) всегда будут округлять ваше число, и выхранить округленные (и, следовательно, неправильные) значения.

Также ваше предположение о округлении до двух десятичных разрядов - откуда это предположение исходит?

select '1.2345678'::float4;
 float4  
---------
 1.23457
(1 row)

Таким образом, до сих пор вы представили рядпредположения и ярлыки, не показывая, почему вы хотите использовать числа с плавающей запятой вместо чисел.Какова ваша веская причина?Просто сохраните несколько байтов?

Мой следующий вопрос: если ваше приложение расширяется и выполняет больше, чем просто "средние" вычисления - вам нужно снова преобразовать тип данных в числовой?

0 голосов
/ 09 мая 2018

Переменные с плавающей точкой уязвимы для ошибок с плавающей точкой. Поэтому, если важна точность (когда речь идет о деньгах), всегда рекомендуется использовать числовой тип.

https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems

Примеры погрешностей с плавающей точкой

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...