Есть ли веская причина хранить проценты меньше 1 как числа больше 1?
Вопрос
Я унаследовал проект, использующий SQL Server 200x, в котором столбец, в котором хранится значение, которое всегда рассматривается как процент в проблемной области, хранится как его эквивалент с точностью более 1 десятичного знака.Например, 70% (0,7, буквально) хранится как 70, 100% как 100, и т. д.Помимо необходимости помнить * 0.01 для извлеченных значений и * 100 перед сохранением значений, само по себе это не кажется проблемой. Хотя у меня от этого голова взрывается...так есть ли веская причина, по которой мне не хватает?Есть ли веские причины это исправить, учитывая, что для работы с псевдопроцентами написано достаточное количество кода?
Есть несколько случаев, когда значение превышает 100%, но я не понимаю, почему бы, например, в таких случаях просто не сохранить значение 1,05.
РЕДАКТИРОВАТЬ:Голова чувствует себя лучше и немного умнее.Спасибо за все идеи.
Решение
На самом деле есть четыре веские причины, по которым я могу подумать, что вы можете сохранить & # 8212 и вычислить с помощью & # 8212; процентные значения целых чисел, а не эквиваленты с плавающей точкой:
<Ол>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 будет занимать меньше места.
Хорошее предположение состоит в том, что все, что вы делаете с целыми числами (хранение, вычисление, вставка в редактирование для пользователя и т. д.), немного проще и эффективнее, чем то же самое с числами с плавающей запятой. И проблемы округления не так очевидны, когда вы смотрите на данные.
Если это числа, которые конечные пользователи могут видеть и взаимодействовать с ними, проценты легче понять, чем десятичные дроби.
Это одна из тех ситуаций, где может помочь вспомогательное средство записи; в программе будьте последовательны в использовании префикса (венгерского) или постфикса для указания значений в процентах по сравнению с десятичными. Если вы можете распространить соглашение об именах на сами поля базы данных, тем лучше.
И чтобы добавить к проблеме хранения данных, если вы можете использовать целочисленную арифметику для любой обработки, которую вы выполняете, производительность намного выше, чем при выполнении арифметики с плавающей запятой ... Поэтому сохранение значений в виде целочисленных значений может позволить обработку логика для выделения целочисленной арифметики
Если вы на самом деле используете их в качестве коэффициента (или ожидаете, что пользователи базы данных будут делать подобные вещи в отчетах), есть смысл сохранить их в качестве коэффициента, особенно если есть причина для выполнения расчетов, включающих больше чем один.
Однако, если вы сделаете это, вы должны быть последовательны - либо все проценты, либо все коэффициенты.