Есть ли веская причина хранить проценты меньше 1 как числа больше 1?

StackOverflow https://stackoverflow.com/questions/288575

  •  08-07-2019
  •  | 
  •  

Вопрос

Я унаследовал проект, использующий SQL Server 200x, в котором столбец, в котором хранится значение, которое всегда рассматривается как процент в проблемной области, хранится как его эквивалент с точностью более 1 десятичного знака.Например, 70% (0,7, буквально) хранится как 70, 100% как 100, и т. д.Помимо необходимости помнить * 0.01 для извлеченных значений и * 100 перед сохранением значений, само по себе это не кажется проблемой. Хотя у меня от этого голова взрывается...так есть ли веская причина, по которой мне не хватает?Есть ли веские причины это исправить, учитывая, что для работы с псевдопроцентами написано достаточное количество кода?

Есть несколько случаев, когда значение превышает 100%, но я не понимаю, почему бы, например, в таких случаях просто не сохранить значение 1,05.

РЕДАКТИРОВАТЬ:Голова чувствует себя лучше и немного умнее.Спасибо за все идеи.

Это было полезно?

Решение

На самом деле есть четыре веские причины, по которым я могу подумать, что вы можете сохранить & # 8212 и вычислить с помощью & # 8212; процентные значения целых чисел, а не эквиваленты с плавающей точкой:

<Ол>
  • В зависимости от выбранных типов данных целочисленное значение может занимать меньше места.
  • В зависимости от типа данных значение с плавающей запятой может потерять точность (помните, что не все языки имеют тип данных, эквивалентный типу SQL Server decimal).
  • Если значение будет вводиться или выводиться пользователю очень часто, может быть удобнее сохранить его в более удобном для пользователя формате (решение между преобразованием при отображении и преобразованием при вычислении ... но посмотрите следующий пункт).
  • Если значения принципа также являются целыми числами, то

    principle * integerPercentage / 100
    

    , которая использует всю целочисленную арифметику, обычно быстрее, чем ее эквивалент с плавающей точкой (вероятно, значительно быстрее в случае типа с плавающей точкой, эквивалентного типу T-SQL <=>).

  • Другие советы

    Если это байтовое поле, то оно занимает меньше места в БД, чем числа с плавающей запятой, но если у вас нет миллионов и миллионов записей, вы вряд ли увидите разницу.

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

    Например

    (0.3==3*.1)
    

    обычно имеет значение Ложь.

    Однако

    abs( 0.3 - 3*.1 )
    

    Это крошечное число (5,55e-17).Но это боль, когда приходится делать все с (column-SomeValue) BETWEEN -0.0001 AND 0.0001 или ABS(column-SomeValue) < 0.0001.Вы бы предпочли сделать column = SomeValue в вашем предложении WHERE.

    Числа с плавающей запятой подвержены ошибкам округления и, следовательно, могут действовать " funny " в сравнении. Если вы всегда хотите иметь дело с ним как с фиксированным десятичным числом, вы можете выбрать десятичный тип, скажем, десятичный (5,2), или выполнить преобразование и сохранить как int, как это делает ваша БД. Вероятно, я бы пошел по десятичному маршруту, хотя int будет занимать меньше места.

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

    Если это числа, которые конечные пользователи могут видеть и взаимодействовать с ними, проценты легче понять, чем десятичные дроби.

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

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

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

    Однако, если вы сделаете это, вы должны быть последовательны - либо все проценты, либо все коэффициенты.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top