Десятичное и целое при использовании 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
Другие вопросы по тегам