Десятичное и целое при использовании ORM
Я использую инструменты / генераторы кода ORM и вижу, что они предпочитают использовать decimal
в int
значения при сопоставлении столбцов со свойствами. Есть ли преимущество использования десятичной дроби?
Тип столбца в базе данных по умолчанию Number
который создан как Number(38, 0)
Я верю.
2 ответа
NUMBER
является NUMBER(38)
, который имеет гораздо больший возможный диапазон, чем int
(Int32
) (и намного больше, чем long
, тоже). double
имеет другую семантику округления, поэтому decimal
предпочтительнее, чтобы избежать ошибок и проблем. Если ORM может гарантировать, что данные вписываются в int
, это может быть счастливее использовать int
,
Десятичный - это 128-битный тип данных. Int32 является 32-разрядным и слишком мал для общего назначения, поскольку таблицы обычно имеют число строк, переполняющее 32-разрядное целое число. Некоторые инструменты по умолчанию просто используют NUMBER(38) или псевдоним INTEGER в Oracle, который сопоставляется с ним, а некоторые инструменты упрощают выход и используют десятичное число, в то время как другие пытаются более точно отобразить соответствующие диапазоны значений.
Учитывая, насколько большим может быть Oracle NUMBER(38) (38 значащих цифр - это большое число), десятичная дробь является единственным безопасным вариантом. Но если вы знаете, что храните последовательные значения, тогда Int64 достаточно практичен, потому что даже Decimal может потенциально переполниться с Oracle NUMBER. Десятичное число может содержать до 79 228 162 514 644 337 593 543 950 335. Это "всего" 29 значащих цифр и все еще не может содержать максимальное значение NUMBER(38).
Если вам нужно более точное сопоставление, вам нужно использовать меньшие по точности поля NUMBER в Oracle. Я использую:
NUMBER(9) => Int32
NUMBER(18) => Int64
NUMBER(19+) => Decimal
в генераторах кода доступа к данным, которые я написал. ORM могут делать то же самое или нет. Обычно NUMBER(18) подходит для любых целочисленных ключей, которые вам когда-либо понадобятся.
Если вы не выполняете арифметику со своими первичными ключами, то я не могу представить себе никакого преимущества в использовании десятичного типа, если вы просто хотите "выстрелить и забыть" и никогда не беспокоиться о значении, которое не подходит. В системах OLTP существует незначительная разница в производительности между использованием десятичного числа и Int64, и Oracle не заботится о том, определяете ли вы поле как NUMBER(1) или NUMBER(38) в том, что касается хранилища данных, тип NUMBER() является Тип переменной длины, такой как VARCHAR, будет занимать столько места, сколько необходимо для определенного значения в каждой строке. Это не хранилище фиксированной длины, поэтому вы ограничиваете только потенциальное значение, а не экономите место.
SQL> insert into bbb values(1);
1 row created.
SQL> insert into bbb values(11111111);
1 row created.
SQL> insert into bbb values(1111111111111111111111111);
1 row created.
SQL> select i, vsize(i) from bbb;
I VSIZE(I)
---------- ----------
1 2
11111111 5
1.1111E+24 14