Сколько места в байтах занимает для хранения ячейка с типом данных NUMBER(p)?
Не могу найти убедительного ответа на следующий вопрос.
Нужно узнать, как много места занимает для хранения значение типа данных NUMBER(p).
Например: NUMBER(1), NUMBER(3), NUMBER(8), NUMBER(10) и т.д..
create table t (x NUMBER(1), y NUMBER(10))
/
select COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE
from user_tab_columns
where table_name='T';
COLUMN_NAME DATA_TYPE DATA_LENGTH DATA_PRECISION DATA_SCALE
------------ ------------ ------------ ---------------- ------------
X NUMBER 22 1 0
Y NUMBER 22 10 0
Получается, независимо от точности, требуется 22 байта. Это действительно так?
Свободный перевод вопроса Oracle NUMBER(p) storage size? от участника @alex_pt
Ответы (1 шт):
Все чиселовые значения хранятся в виде поля переменной длины от 0 до 22 байт. Размер занимаемый для хранения зависит от фактического числового значения, а также от точности и количества знаков после запятой.
В документации Database Concepts / Numeric Data Types сказано:
Oracle Database stores numeric data in variable-length format. Each value is stored in scientific notation, with 1 byte used to store the exponent. The database uses up to 20 bytes to store the mantissa, which is the part of a floating-point number that contains its significant digits. Oracle Database does not store leading and trailing zeros.
Более интересно о хранении числовых значений повествуется в книге Expert Oracle Database Architecture (один из авторов: Томас Кайт). Цитирую (источник: блог Томаса Кайта):
It is interesting and useful to note that the NUMBER type is in fact a varying length data type on disk and will consume between 0 and 22 bytes of storage. Many times, programmers consider a numeric datatype to be a fixed length type and that is what they typically see when programming with 2 or 4 byte integers and 4 or 8 byte floats. The Oracle NUMBER type is similar to a varying length character string.
Можно посмотреть, что происходит с числами, содержащими разное количество значащих цифр. Создадим таблицу с двумя столбцами чисел и заполним первый столбец числами, содержащими 2, 4, 6, ..., 38 значащих цифр. Затем, просто добавим 1 к каждому из них:
create table t ( x number, y number )
/
insert into t (x, y)
select x, x+1 from (
select to_number (rpad ('9', rownum*2, '9')) x
from dual connect by level<=19);
Стандартная функция VSIZE покажет, сколько места в байтах занимает значение в столбце:
X Y XS YS
---------------------------------------- ---------------------------------------- -- --
99 100 2 2
9999 10000 3 2
999999 1000000 4 2
99999999 100000000 5 2
9999999999 10000000000 6 2
999999999999 1000000000000 7 2
99999999999999 100000000000000 8 2
9999999999999999 10000000000000000 9 2
999999999999999999 1000000000000000000 10 2
99999999999999999999 100000000000000000000 11 2
9999999999999999999999 10000000000000000000000 12 2
999999999999999999999999 1000000000000000000000000 13 2
99999999999999999999999999 100000000000000000000000000 14 2
9999999999999999999999999999 10000000000000000000000000000 15 2
999999999999999999999999999999 1000000000000000000000000000000 16 2
99999999999999999999999999999999 100000000000000000000000000000000 17 2
9999999999999999999999999999999999 10000000000000000000000000000000000 18 2
999999999999999999999999999999999999 1000000000000000000000000000000000000 19 2
99999999999999999999999999999999999999 100000000000000000000000000000000000000 20 2
При добавлении значащих цифр, требуемый объем памяти занимает все больше места. Каждые 2 цифры увеличивают объем памяти еще на один байт. Но если прибавить к этому значению единицу, что увеличит длину ещё на один знак, то занимаемое место постоянно 2 байта. БД пытается для сохранения числа выделить как можно меньше места. Для этого сохраняются значащие цифры, экспонента, используемая для десятичной точки, и знак числа (положительный или отрицательный).
Таким образом, чем больше значащих цифр содержит число, тем больше места для хранения оно требует.
Полезно знать, что числа хранятся в полях переменной длины. При попытке определить размер таблицы, например, чтобы оценить, какой объем памяти на диске потребуется для хранения 1.000.000 строк в таблице. Будут ли числа занимать 2 байта или 20 байт? Точно оценить размер таблицы без репрезентативных тестовых данных очень сложно.