8.1. Числовые типы
Числовые типы включают двух-, четырёх- и восьмибайтные целые, четырёх- и восьмибайтные числа с плавающей точкой, а также десятичные числа с задаваемой точностью. Все эти типы перечислены в Таблице 8.2.
Таблица 8.2. Числовые типы
Имя | Размер | Описание | Диапазон |
---|---|---|---|
smallint | 2 байта | целое в небольшом диапазоне | -32768 .. +32767 |
integer | 4 байта | типичный выбор для целых чисел | -2147483648 .. +2147483647 |
bigint | 8 байт | целое в большом диапазоне | -9223372036854775808 .. 9223372036854775807 |
decimal | переменный | вещественное число с указанной точностью | до 131072 цифр до десятичной точки и до 16383 — после |
numeric | переменный | вещественное число с указанной точностью | до 131072 цифр до десятичной точки и до 16383 — после |
real | 4 байта | вещественное число с переменной точностью | точность в пределах 6 десятичных цифр |
double precision | 8 байт | вещественное число с переменной точностью | точность в пределах 15 десятичных цифр |
smallserial | 2 байта | небольшое целое с автоувеличением | 1 .. 32767 |
serial | 4 байта | целое с автоувеличением | 1 .. 2147483647 |
bigserial | 8 байт | большое целое с автоувеличением | 1 .. 9223372036854775807 |
Синтаксис констант числовых типов описан в Подразделе 4.1.2. Для этих типов определён полный набор соответствующих арифметических операторов и функций. За дополнительными сведениями обратитесь к Главе 9. Подробнее эти типы описаны в следующих разделах.
8.1.1. Целочисленные типы
Типы smallint
, integer
и bigint
хранят целые числа, то есть числа без дробной части, имеющие разные допустимые диапазоны. Попытка сохранить значение, выходящее за рамки диапазона, приведёт к ошибке.
Чаще всего используется тип integer
, как наиболее сбалансированный выбор ширины диапазона, размера и быстродействия. Тип smallint
обычно применяется, только когда крайне важно уменьшить размер данных на диске. Тип bigint
предназначен для тех случаев, когда числа не умещаются в диапазон типа integer
.
В SQL определены только типы integer
(или int
), smallint
и bigint
. Имена типов int2
, int4
и int8
выходят за рамки стандарта, хотя могут работать и в некоторых других СУБД.
8.1.2. Числа с произвольной точностью
Тип numeric
позволяет хранить числа с очень большим количеством цифр. Он особенно рекомендуется для хранения денежных сумм и других величин, где важна точность. Вычисления с типом numeric
дают точные результаты, где это возможно, например, при сложении, вычитании и умножении. Однако операции со значениями numeric
выполняются гораздо медленнее, чем с целыми числами или с типами с плавающей точкой, описанными в следующем разделе.
Ниже мы используем следующие термины: точность значения numeric
определяет общее количество значащих цифр во всём числе, то есть количество цифр с двух сторон от десятичной точки. Масштаб numeric
определяет количество десятичных цифр в дробной части, справа от десятичной точки. Например, число 23.5141 имеет точность 6 и масштаб 4. Целочисленные значения можно считать числами с масштабом 0.
Для столбца типа numeric
можно настроить и максимальную точность, и максимальный масштаб. Столбец типа numeric
объявляется следующим образом:
NUMERIC(точность
,масштаб
)
Точность должна быть положительной, а масштаб положительным или равным нулю. Альтернативный вариант
NUMERIC(точность
)
устанавливает масштаб 0. Форма:
NUMERIC
без указания точности и масштаба создаёт столбец, в котором можно сохранять числовые значения любой точности и масштаба в пределах, поддерживаемых системой. В столбце этого типа входные значения не будут приводиться к какому-либо масштабу, тогда как в столбцах numeric
с явно заданным масштабом значения подгоняются под этот масштаб. (Стандарт SQL утверждает, что по умолчанию должен устанавливаться масштаб 0, т. е. значения должны приводиться к целым числам. Однако мы считаем это не очень полезным. Если для вас важна переносимость, всегда указывайте точность и масштаб явно.)
Примечание
Максимально допустимая точность, которую можно указать в объявлении типа, равна 1000; если же использовать NUMERIC
без указания точности, действуют ограничения, описанные в Таблице 8.2.
Если масштаб значения, которое нужно сохранить, превышает объявленный масштаб столбца, система округлит его до заданного количества цифр после точки. Если же после этого количество цифр слева в сумме с масштабом превысит объявленную точность, произойдёт ошибка.
Числовые значения физически хранятся без каких-либо дополняющих нулей слева или справа. Таким образом, объявляемые точность и масштаб столбца определяют максимальный, а не фиксированный размер хранения. (В этом смысле тип numeric
больше похож на тип varchar(
, чем на n
)char(
.) Действительный размер хранения такого значения складывается из двух байт для каждой группы из четырёх цифр и дополнительных трёх-восьми байт.n
)
Помимо обычных чисел тип numeric
позволяет сохранить специальное значение NaN
, что означает «not-a-number» (не число). Любая операция c NaN
выдаёт в результате тоже NaN
. Записывая это значение в виде константы в команде SQL, его нужно заключать в апострофы, например так: UPDATE table SET x = 'NaN'
. Регистр символов в строке NaN
не важен.
Примечание
В большинстве реализаций «не число» (NaN
) считается не равным любому другому значению (в том числе и самому NaN
). Чтобы значения numeric
можно было сортировать и использовать в древовидных индексах, Postgres Pro считает, что значения NaN
равны друг другу и при этом больше любых числовых значений (не NaN
).
Типы decimal
и numeric
равнозначны. Оба эти типа описаны в стандарте SQL.
8.1.3. Типы с плавающей точкой
Типы данных real
и double precision
хранят приближённые числовые значения с переменной точностью. На практике эти типы обычно реализуют стандарт IEEE 754 для двоичной арифметики с плавающей точкой (с одинарной и двойной точностью соответственно), в той мере, в какой его поддерживают процессор, операционн��я система и компилятор.
Неточность здесь выражается в том, что некоторые значения, которые нельзя преобразовать во внутренний формат, сохраняются приближённо, так что полученное значение может несколько отличаться от записанного. Управление подобными ошибками и их распространение в процессе вычислений является предметом изучения целого раздела математики и компьютерной науки, и здесь не рассматривается. Мы отметим только следующее:
Если вам нужна точность при хранении и вычислениях (например, для денежных сумм), используйте вместо этого тип
numeric
.Если вы хотите выполнять с этими типами сложные вычисления, имеющие большую важность, тщательно изучите реализацию операций в вашей среде и особенно поведение в крайних случаях (бесконечность, антипереполнение).
Проверка равенства двух чисел с плавающей точкой может не всегда давать ожидаемый результат.
На большинстве платформ тип real
может сохранить значения в пределах от 1E-37 до 1E+37 с точностью не меньше 6 десятичных цифр. Тип double precision
предлагает значения в диапазоне от 1E-307 до 1E+308 и с точностью не меньше 15 цифр. Попытка сохранить слишком большие или слишком маленькие значения приведёт к ошибке. Если точность вводимого числа слишком велика, оно будет округлено. При попытке сохранить число, близкое к 0, но непредставимое как отличное от 0, произойдёт ошибка антипереполнения.
Примечание
Параметр extra_float_digits определяет количество дополнительных значащих цифр при преобразовании значения с плавающей точкой в текст для вывода. Со значением по умолчанию (0
) вывод будет одинаковым на всех платформах, поддерживаемых Postgres Pro. При его увеличении выводимое значение числа будет более точно представлять хранимое, но от этого может пострадать переносимость.
В дополнение к обычным числовым значениям типы с плавающей точкой могут содержать следующие специальные значения:
Infinity
-Infinity
NaN
Они представляют особые значения, описанные в IEEE 754, соответственно «бесконечность», «минус бесконечность» и «не число». (На компьютерах, где арифметика с плавающей точкой не соответствует стандарту IEEE 754, эти значения, вероятно, не будут работать должным образом.) Записывая эти значения в виде констант в команде SQL, их нужно заключать в апострофы, например так: UPDATE table SET x = 'Infinity'
. Регистр символов в этих строках не важен.
Примечание
Согласно IEEE754, NaN
не должно считаться равным любому другому значению с плавающей точкой (в том числе и самому NaN
). Чтобы значения с плавающей точкой можно было сортировать и использовать в древовидных индексах, Postgres Pro считает, что значения NaN
равны друг другу, и при этом больше любых числовых значений (не NaN
).
Postgres Pro также поддерживает форматы float
и float(
, оговорённые в стандарте SQL, для указания неточных числовых типов. Здесь p
)p
определяет минимально допустимую точность в двоичных цифрах. Postgres Pro воспринимает запись от float(1)
до float(24)
как выбор типа real
, а запись от float(25)
до float(53)
как выбор типа double precision
. Значения p
вне допустимого диапазона вызывают ошибку. Если float
указывается без точности, подразумевается тип double precision
.
Примечание
Предположение, что типы real
и double precision
имеют в мантиссе 24 и 53 бита соответственно, справедливо для всех реализаций плавающей точки по стандарту IEEE. На платформах, не поддерживающих IEEE, размер мантиссы может несколько отличаться, но для простоты диапазоны p
везде считаются одинаковыми.
8.1.4. Последовательные типы
Типы данных smallserial
, serial
и bigserial
не являются настоящими типами, а представляют собой просто удобное средство для создания столбцов с уникальными идентификаторами (подобное свойству AUTO_INCREMENT
в некоторых СУБД). В текущей реализации запись:
CREATE TABLEимя_таблицы
(имя_столбца
SERIAL );
равнозначна следующим командам:
CREATE SEQUENCEимя_таблицы
_имя_столбца
_seq; CREATE TABLEимя_таблицы
(имя_столбца
integer NOT NULL DEFAULT nextval('имя_таблицы
_имя_столбца
_seq') ); ALTER SEQUENCEимя_таблицы
_имя_столбца
_seq OWNED BYимя_таблицы
.имя_столбца
;
То есть при определении такого типа создаётся целочисленный столбец со значением по умолчанию, извлекаемым из генератора последовательности. Чтобы в столбец нельзя было вставить NULL, в его определение добавляется ограничение NOT NULL
. (Во многих случаях также имеет смысл добавить для этого столбца ограничения UNIQUE
или PRIMARY KEY
для защиты от ошибочного добавления дублирующихся значений, но автоматически это не происходит.) Послед��яя команда определяет, что последовательность «принадлежит» столбцу, так что она будет удалена при удалении столбца или таблицы.
Примечание
Так как типы smallserial
, serial
и bigserial
реализованы через последовательности, в числовом ряду значений столбца могут образовываться пропуски (или "дыры"), даже если никакие строки не удалялись. Значение, выделенное из последовательности, считается "задействованным", даже если строку с этим значением не удалось вставить в таблицу. Это может произойти, например, при откате транзакции, добавляющей данные. См. описание nextval()
в Разделе 9.16.
Чтобы вставить в столбец serial
следующее значение последовательности, ему нужно присвоить значение по умолчанию. Это можно сделать, либо исключив его из списка столбцов в операторе INSERT
, либо с помощью ключевого слова DEFAULT
.
Имена типов serial
и serial4
равнозначны: они создают столбцы integer
. Так же являются синонимами имена bigserial
и serial8
, но они создают столбцы bigint
. Тип bigserial
следует использовать, если за всё время жизни таблицы планируется использовать больше чем 231 значений. И наконец, синонимами являются имена типов smallserial
и serial2
, но они создают столбец smallint
.
Последовательность, созданная для столбца serial
, автоматически удаляется при удалении связанного столбца. Последовательность можно удалить и отдельно от столбца, но при этом также будет удалено определение значения по умолчанию.