Разница между числовым, плавающим и десятичным в SQL Server

322

Каковы различия между numeric, floatи decimalтипы данных и которые должны быть использованы в каких ситуациях?

Для любого вида финансовой транзакции (например, для поля зарплаты), какая из них предпочтительнее и почему?

priyanka.sarkar
источник
1
Десятичная и числовая ссылка выше требует обновления до docs.microsoft.com/en-us/sql/t-sql/data-types/… . Ссылка выше больше не существует.
Найджел Эйнско
1
Обычно при работе с финансовыми объектами интересно работать с целочисленными типами, кроме с плавающей точкой , и хранить значения, например, в центах , а не в долларах .
Педро

Ответы:

494

используйте типы данных float или real, только если точность, обеспечиваемая десятичной дробью (до 38 цифр), недостаточна

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

  • Избегайте использования плавающих или вещественных столбцов в условиях поиска предложения WHERE, особенно операторов = и <> ( Technet )

как правило, потому что точность, обеспечиваемая десятичной дробью, составляет [10E38 ~ 38 цифр], если ваш номер может в нее поместиться, и меньший объем памяти (и, возможно, скорость) Float не важен, и дело с ненормальным поведением и проблемами приближенных числовых типов не является допустимо, используйте десятичную вообще .

больше полезной информации

  • числовой = десятичный (от 5 до 17 байт) ( точный числовой тип данных)
    • будет отображаться в десятичный в .NET
    • оба имеют (18, 0) параметры по умолчанию (точность, масштаб) в SQL-сервере
    • шкала = максимальное количество десятичных цифр, которое можно сохранить справа от десятичной точки.
    • учтите, что money (8 байт) и smallmoney (4 байт) также точны и соответствуют десятичному знаку в .NET и имеют 4 десятичных знака ( MSDN )
    • десятичное и числовое (Transact-SQL) - MSDN
  • действительный (4 байта) ( приблизительный числовой тип данных)
  • float (8 байт) ( приблизительно) числовой тип данных)
    • будет отображаться в Double в .NET
  • Все точные числовые типы всегда дают один и тот же результат, независимо от того, какой тип архитектуры процессора используется. или величины чисел
  • Параметр, предоставленный типу данных с плавающей точкой, определяет количество битов, которые используются для хранения мантиссы числа с плавающей запятой .
  • Приблизительный числовой тип данных обычно использует меньше места для хранения и имеет лучшую скорость (до 20x), и вы также должны учитывать, когда они были преобразованы в .NET

Точные числовые типы данных Приблизительные числовые типы данных

основной источник : MCTS Self-Paced Training Kit (экзамен 70-433): Разработка баз данных Microsoft® SQL Server® 2008 - Глава 3 - Таблицы, типы данных и декларативная целостность данных Урок 1 - Выбор типов данных (рекомендации) - Страница 93

Иман
источник
17
use the float or real data types only if the precision provided by decimal is insufficient- Я думал, что реальный МЕНЬШЕ точнее десятичного, так почему же вы пишете, чтобы использовать реальный, если десятичного числа недостаточно?
BornToCode
7
Вещество менее точно, поэтому не рекомендуется, если не требуется хранить большие числа, превышающие десятичное (> 10e38), или из соображений пространства. Я предполагаю, что точность здесь в кавычке означает возможные значения и величину, а не точность
Иман
12
@BornToCode «Точность» здесь относится к тому, насколько широки значения, которые вы хотите сохранить. если вам нужно сохранить значения между 1e10 и 1e-10, то decimalвсе будет в порядке. Это точность 20. Если вам нужно хранить значения между, скажем, 1e20 и 1e-20, ну, decimal вы не можете этого сделать. Это 40 цифр точности. Вы никогда не сможете хранить 1e20 и 1e-20 в одном decimalполе. Вместо этого вы можете использовать float, который внутренне сохраняет все как журнал базы 2. Это обеспечивает полный диапазон точности в одном поле с недостатком, что только первые ~ 8 цифр будут точными.
Бекон Бит
Я третий комментарии BornToCode и Iman. Я только что экспериментировал (с использованием SQL Server 2012), и кажется, что машина epsilon для float (53), тип с плавающей запятой с самой высокой точностью, - 2.22044604925031E-16. Таким образом, вы получите около 15 значимых цифр из этого. С другой стороны, я могу получить 38 значащих цифр из десятичного числа.
Стюарт
«Используй float...» - сказал кто? Это цитата или ваше мнение?
user443854
24

Рекомендации MSDN: использование десятичных, плавающих и реальных данных

Максимальная точность по умолчанию для числовых и десятичных типов данных - 38. В Transact-SQL числовое значение функционально эквивалентно десятичному типу данных. Используйте десятичный тип данных для хранения чисел с десятичными знаками, когда значения данных должны храниться точно так, как указано.

Поведение float и real соответствует спецификации IEEE 754 для приблизительных числовых типов данных. Из-за приблизительной природы типов данных с плавающей запятой и реальных данных не используйте эти типы данных, когда требуется точное числовое поведение, например, в финансовых приложениях, в операциях, связанных с округлением или при проверках на равенство. Вместо этого используйте типы данных integer, decimal, money или smallmoney. Избегайте использования плавающих или вещественных столбцов в условиях поиска предложения WHERE, особенно операторов = и <>. Лучше ограничить плавающие и реальные столбцы> или <сравнениями.

kmote
источник
(Фиксированное) количество десятичных знаков указывается в Scaleстолбце.
Сис Тиммерман,
1
Если вы хотите «точно так, как указано», то, с точки зрения стандартов, есть некоторое преимущество, numericпоскольку оно никогда не будет хранить с большей точностью, чем вы просили: см. Stackoverflow.com/a/759606/626804
Эд Авис,
13

Не полный ответ, а полезная ссылка:

«Я часто делаю вычисления с десятичными значениями. В некоторых случаях приведение десятичных значений к плавающим значениям КАК МОЖНО СКОРЕЕ, перед любыми вычислениями дает лучшую точность»

http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/12/20/for-better-precision-cast-decimals-before-calculations.aspx

Аляска
источник
2
Это не имеет смысла. Все остальные ответы, включая источники, говорят, что числовые или десятичные типы данных являются точными, а плавающие или действительные типы очень близки. Из-за более низкой точности я могу понять, что приведение к плавающей точке может позволить более быстрые вычисления, но не более высокую точность.
cbaldan
3
Все числовые типы данных могут испытывать переполнение и переполнение. Переполнение является явной ошибкой, однако, при переполнении молчит. Характеристики недополнения для decimalи floatмогут отличаться . Десятичная дробь максимально защищает от потери, увеличивая точность или масштаб. Однако, как только вы достигнете предела значащих цифр в десятичном выражении, потери значения будут молчать (и точность теряется). Float имеет более широкий диапазон возможных масштабов, и его ограничения на самом деле являются причиной недостаточного масштабирования. Таким образом, поплавок может иметь лучший масштаб. Тем не менее, это все еще неточный тип.
ErikE
13

Они различаются по приоритету типа данных

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

SELECT SQL_VARIANT_PROPERTY(CAST(1 AS NUMERIC) + CAST(1 AS DECIMAL),'basetype')

Результирующий тип данных является числовым, поскольку он имеет приоритет над типом данных .

Исчерпывающий список типов данных по приоритету:

Ссылка ссылка

Stephan
источник
7

Десятичная имеет фиксированную точность, в то время как float имеет переменную точность.

РЕДАКТИРОВАТЬ (не удалось прочитать весь вопрос): Float (53) (он же настоящий) - это число с плавающей запятой двойной точности (32-разрядное) в SQL Server. Regular Float - это число с плавающей запятой одинарной точности. Double - хорошая комбинация точности и простоты для многих вычислений. Вы можете создать число с очень высокой точностью с десятичным числом - до 136-битных - но вы также должны быть осторожны, чтобы правильно определить свою точность и масштаб, чтобы он мог содержать все ваши промежуточные вычисления с необходимым количеством цифр.

Брайан Райтер
источник
Вы не указали, какой вариант предпочтительнее, если дело касается финансовой сделки и почему?
priyanka.sarkar
В SQL Server 2008 и более поздних версиях float (53), также известный как float, представляет собой число с плавающей запятой двойной (64-разрядной) точности, в то время как float (24), aka real, представляет собой число с плавающей запятой одинарной (32-разрядной) точности. docs.microsoft.com/en-us/sql/t-sql/data-types/float-and-real-transact-sql
М Клостер,
4

Float - это тип данных Приблизительное число, что означает, что не все значения в диапазоне типов данных могут быть представлены точно.

Десятичный / Числовой тип данных с фиксированной точностью, что означает, что все значения в диапазоне типов данных могут быть представлены точно с точностью и масштабом. Вы можете использовать десятичную для экономии денег.

Преобразование из десятичного или числового в плавающее может привести к некоторой потере точности. Для типов данных Десятичный или Числовой SQL Server рассматривает каждую конкретную комбинацию точности и масштаба как отдельный тип данных. DECIMAL (2,2) и DECIMAL (2,4) - это разные типы данных. Это означает, что 11.22 и 11.2222 - это разные типы, хотя в случае с плавающей точкой это не так. Для FLOAT (6) 11.22 и 11.2222 являются одинаковыми типами данных.

Вы также можете использовать тип данных деньги для экономии денег. Это собственный тип данных с точностью до 4 цифр для денег. Большинство экспертов предпочитают этот тип данных для экономии денег.

Ссылка 1 2 3

Сомнат Мулук
источник
3

Дело в десятичной

Какая это основная потребность?

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

Учти это:

0.1 (decimal, or "base 10") = .00011001100110011... (binary, or "base 2")

Вышеуказанный многоточие [...] означает «бесконечный». Если вы внимательно посмотрите на это, существует бесконечный повторяющийся паттерн (= '0011')

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

Скажем, вы хотите хранить финансовые суммы (это числа, которые могут иметь дробную часть). Прежде всего, вы не можете использовать целые числа явно (целые числа не имеют дробной части). С чисто математической точки зрения естественной тенденцией будет использование float. Но в компьютере числа с плавающей точкой имеют часть числа, которая находится после десятичной точки - «мантисса» - ограниченная. Это приводит к ошибкам округления.

Чтобы преодолеть это, компьютеры предлагают определенные типы данных, которые ограничивают двоичную ошибку округления в компьютерах для десятичных чисел. Это тип данных, который обязательно должен использоваться для представления финансовых сумм. Эти типы данных обычно идут по имени Decimal. Так обстоит дело, например, в C #. Или DECIMALв большинстве баз данных.

Варус септимус
источник
1

Хотя этот вопрос не включает тип данных MONEY, некоторые люди, сталкивающиеся с этим потоком, могут испытывать искушение использовать тип данных MONEY для финансовых расчетов.

Будьте осторожны с типом данных MONEY, он имеет ограниченную точность.

В ответах на этот вопрос Stackoverflow много полезной информации об этом:

Следует ли вам выбирать типы данных MONEY или DECIMAL (x, y) в SQL Server?

Саймон Тьюси
источник