8.1. Числовые типы#
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
являются расширениями, которые также используются некоторыми
другими системами баз данных SQL.
8.1.2. Произвольная точность чисел
Тип numeric
может хранить числа с очень большим количеством цифр. Он особенно рекомендуется для хранения денежных сумм и других величин, где требуется точность. Вычисления с значениями типа numeric
дают точные результаты, если это возможно, например, сложение, вычитание, умножение. Однако вычисления с значениями типа numeric
очень медленные по сравнению с целочисленными типами или с плавающей запятой, описанными в следующем разделе.
Мы используем следующие термины ниже: Точность типа numeric
- это общее количество значащих цифр в целом числе, то есть количество цифр с обеих сторон десятичной точки. Масштаб типа numeric
- это количество десятичных цифр в дробной части, справа от десятичной точки. Таким образом, число 23.5141 имеет точность 6 и масштаб 4. Целые числа можно считать имеющими масштаб ноль.
Максимальная точность и максимальный масштаб столбца типа numeric
могут быть настроены. Чтобы объявить столбец типа numeric
, используйте синтаксис:
NUMERIC(precision
,scale
)
Точность должна быть положительной, в то время как масштаб может быть положительным или отрицательным (см. ниже). Вариант:
NUMERIC(precision
)
выбирает масштаб 0. Указание:
NUMERIC
без указания точности или масштаба создает “неограниченный числовой” столбец, в котором можно хранить числовые значения любой длины, до пределов реализации. Столбец этого типа не приводит входные значения к определенному масштабу, в то время как столбцы numeric
с указанным масштабом приводят входные значения к этому масштабу. (Стандарт SQL требует масштаба по умолчанию равного 0, т.е. приведения к целочисленной точности. Мы считаем это немного бесполезным. Если вам важна переносимость, всегда явно указывайте точность и масштаб).
Примечание
Максимальная точность, которую можно явно указать в объявлении типа numeric
, составляет 1000. Неограниченный столбец numeric
подчиняется ограничениям, описанным в Таблица 8.2.
Если масштаб значения, которое нужно сохранить, больше объявленного масштаба столбца, система округлит значение до указанного количества десятичных знаков. Затем, если количество цифр слева от десятичной точки превышает объявленную точность минус объявленный масштаб, возникает ошибка. Например, столбец, объявленный как
NUMERIC(3, 1)
округлит значения до 1 десятичного знака и может хранить значения в диапазоне от -99.9 до 99.9 включительно.
Начиная с Tantor BE 15, разрешено
объявлять столбец типа numeric
с отрицательной шкалой. Тогда
значения будут округляться влево от десятичной точки.
Точность по-прежнему представляет максимальное количество нераспределенных цифр.
Таким образом, столбец, объявленный как
NUMERIC(2, -3)
будет округлять значения до ближайшей тысячи и может хранить значения в диапазоне от -99000 до 99000 включительно. Также можно объявлять масштаб больше объявленной точности. Такой столбец может содержать только дробные значения, и требуется, чтобы количество нулевых цифр справа от десятичной точки было не меньше объявленного масштаба минус объявленная точность. Например, столбец, объявленный как
NUMERIC(3, 5)
будет округлять значения до 5 десятичных знаков и может хранить значения в диапазоне от -0.00999 до 0.00999 включительно.
Примечание
Tantor BE позволяет задавать масштаб в объявлении типа numeric
с любым значением в диапазоне от -1000 до 1000. Однако стандарт SQL требует, чтобы масштаб находился в диапазоне от 0 до precision
. Использование масштабов за пределами этого диапазона, возможно, нельзя будет перенести на другие системы баз данных.
Числовые значения хранятся физически без дополнительных ведущих или
завершающих нулей. Таким образом, заявленная точность и масштаб столбца
являются максимумами, а не фиксированными выделениями. (В этом смысле тип
numeric
более похож на varchar(
,
чем на n
)char(
). Фактическое требование к
памяти составляет два байта для каждой группы из четырех десятичных цифр,
плюс от трех до восьми байтов издержек.
n
)
В дополнение к обычным числовым значениям, тип numeric
имеет несколько специальных значений:
Infinity
-Infinity
NaN
Эти значения взяты из стандарта IEEE 754 и представляют собой
“бесконечность”, “отрицательную бесконечность” и
“не число” соответственно. При записи этих значений
в виде констант в SQL-команде, надо заключить их в кавычки,
например UPDATE table SET x = '-Infinity'
.
При вводе эти строки распознаются без учета регистра.
Значения бесконечности также могут быть записаны как inf
и -inf
.
Бесконечные значения ведут себя согласно математическим ожиданиям. Например, Infinity
плюс любое конечное значение равно Infinity
, также как и Infinity
плюс Infinity
. Однако Infinity
минус Infinity
дает NaN
(не число), потому что это не имеет четкого определения. Обратите внимание, что бесконечность может быть сохранена только в неограниченном столбце numeric
, так как она фактически превышает любое конечное ограничение точности.
Значение NaN
(не число) используется для представления неопределенных результатов вычислений. Обычно, любая операция с входным значением NaN
приводит к получению другого значения NaN
. Единственное исключение - когда другие входные значения операции таковы, что при замене NaN
на любое конечное или бесконечное числовое значение будет получен тот же самый результат; в этом случае, это значение используется и для NaN
. (Примером этого принципа является то, что NaN
, возведенное в степень ноль, равно единице).
Примечание
В большинстве реализаций концепция "не число" (“not-a-number”) не считается равной любому другому числовому значению (включая NaN
). Чтобы позволить сортировку и использование значений типа numeric
в древовидных индексах, Tantor BE рассматривает значения NaN
как равные и большие, чем все значения, не являющиеся NaN
.
Типы decimal
и numeric
эквивалентны. Оба типа являются частью стандарта SQL.
При округлении значений тип numeric
округляет значения в сторону от нуля, в то время как (на большинстве машин) типы real
и double precision
округляют значения к ближайшему четному числу. Например:
SELECT x, round(x::numeric) AS num_round, round(x::double precision) AS dbl_round FROM generate_series(-3.5, 3.5, 1) as x; x | num_round | dbl_round ------+-----------+----------- -3.5 | -4 | -4 -2.5 | -3 | -2 -1.5 | -2 | -2 -0.5 | -1 | -0 0.5 | 1 | 0 1.5 | 2 | 2 2.5 | 3 | 2 3.5 | 4 | 4 (8 rows)
8.1.3. Типы с плавающей точкой
Типы данных real
и double precision
являются нечеткими числовыми типами переменной точности. На всех текущих поддерживаемых платформах эти типы являются реализациями IEEE Standard 754 для двоичной арифметики с плавающей запятой (соответственно одинарной и двойной точности), в той мере, в которой это поддерживается базовым процессором, операционной системой и компилятором.
«Приближенный» означает, что некоторые значения не могут быть точно преобразованы во внутренний формат и хранятся как приближения, так что при сохранении и извлечении значения могут быть небольшие расхождения. Управление этими ошибками и алгоритм их распространения через вычисления является предметом отдельной области математики и компьютерных наук и не будет обсуждаться в данном документе, за исключением следующих моментов:
Если вам требуется точное хранение и вычисления (например, для денежных сумм), используйте тип
numeric
вместо этого.Если необходимо выполнять сложные вычисления с этими типами для критических задач, особенно если вы полагаетесь на определенное поведение в граничных случаях (бесконечность, потеря значимости), рекомендуем провести детальную оценку их использования.
Сравнение двух значений с плавающей запятой на равенство может не всегда работать ожидаемым образом.
На всех текущих поддерживаемых платформах тип real
имеет диапазон от примерно 1E-37 до 1E+37 с точностью не менее 6 десятичных знаков. Тип double precision
имеет диапазон в районе 1E-307 до 1E+308 с точностью не менее 15 знаков. Значения, которые слишком велики или слишком малы, вызовут ошибку. Округление может произойти, если точность входного числа слишком высока. Числа, стремящиеся к нулю и которые не представляются отличными от нуля, вызовут ошибку потерю значимости.
По умолчанию, значения с плавающей запятой выводятся в текстовой форме в их
наиболее точном десятичном представлении; десятичное значение, полученное,
ближе к истинному двоичному значению, чем к любому другому значению,
представимому в той же двоичной точности. (Однако, выводимое значение
в настоящее время никогда не находится точно между двумя
представимыми значениями, чтобы избежать распространенной ошибки, когда входные
процедуры не правильно учитывают правило округления до ближайшего четного). Это значение будет
использовать не более 17 значащих десятичных цифр для значений float8
и не более 9 цифр для значений float4
.
Примечание
Данный самый короткий и точный формат вывода генерируется намного быстрее, чем прежний округленный формат.
Для обеспечения совместимости с выводом, созданным более старыми версиями PostgreSQL, а также для возможности уменьшения точности вывода, параметр extra_float_digits может быть использован для выбора округленного десятичного вывода. Установка значения 0 восстанавливает предыдущее значение по умолчанию, округляющее значение до 6 (для типа float4
) или 15 (для типа float8
) значащих десятичных цифр. Установка отрицательного значения дополнительно уменьшает количество цифр; например, -2 округляет вывод до 4 или 13 цифр соответственно.
Любое значение extra_float_digits больше 0 выбирает самый короткий и точный формат.
Примечание
Приложения, которым требуются точные значения, всегда должны были устанавливать extra_float_digits равным 3, чтобы получить их. Для максимальной совместимости между версиями необходимо продолжать выставлять данное значение.
В дополнение к обычным числовым значениям, типы с плавающей точкой имеют несколько специальных значений:
Infinity
-Infinity
NaN
Эти значения представляют специальные значения IEEE 754: “бесконечность”, “отрицательная бесконечность” и “не число” соответственно. При записи этих значений в виде констант в SQL-команде, вы должны заключить их в кавычки, например UPDATE table SET x = '-Infinity'
. При вводе эти строки распознаются без учета регистра. Значения бесконечности также могут быть записаны как inf
и -inf
.
Примечание
IEEE 754 определяет, что NaN
не должно сравниваться равным
никакому другому значению с плавающей запятой (включая NaN
).
Чтобы позволить сортировку значений с плавающей запятой и использование
в индексах на основе деревьев, Tantor BE обрабатывает
значения NaN
как равные и большие, чем все
значения, не являющиеся NaN
.
Tantor BE также поддерживает стандартные обозначения SQL для нечетких числовых типов: float
и float(
. Здесь p
)p
указывает минимально допустимую точность в двоичных разрядах. Tantor BE принимает значения от float(1)
до float(24)
как тип real
, а значения от float(25)
до float(53)
выбирают тип double precision
. Значения p
вне допустимого диапазона вызывают ошибку. Если точность не указана для float
, то это означает double precision
.
8.1.4. Типы серий
Примечание
Этот раздел описывает специфический для PostgreSQL способ создания автоинкрементного столбца. Другой способ - использовать стандарт SQL-столбец идентификатора, описанный в CREATE TABLE.
Типы данных smallserial
, serial
и bigserial
не являются настоящими типами, а используются для удобства обозначений при создании столбцов с уникальными идентификаторами (аналогично свойству AUTO_INCREMENT
, поддерживаемому некоторыми другими базами данных). В текущей реализации, указание:
CREATE TABLEtablename
(colname
SERIAL );
эквивалентно указанию:
CREATE SEQUENCEtablename
_colname
_seq AS integer; CREATE TABLEtablename
(colname
integer NOT NULL DEFAULT nextval('tablename
_colname
_seq') ); ALTER SEQUENCEtablename
_colname
_seq OWNED BYtablename
.colname
;
Таким образом, мы создали столбец целого типа и установили его значения по умолчанию из генератора последовательностей. К столбцу применяется ограничение NOT NULL
, чтобы гарантировать, что значение NULL не может быть вставлено. (В большинстве случаев вы также захотите присоединить ограничение UNIQUE
или PRIMARY KEY
, чтобы предотвратить случайную вставку дублирующихся значений, но это не происходит автоматически). Наконец, последовательность помечается как “owned by” столбцом, чтобы она была удалена, если столбец или таблица будет удалена.
Примечание
Поскольку типы данных smallserial
, serial
и bigserial
реализованы с использованием последовательностей, в столбце может возникнуть "пробел" или разрыв в последовательности значений, даже если строки никогда не удаляются. Значение, выделенное из последовательности, все равно "используется", даже если строка, содержащая это значение, никогда не будет успешно вставлена в столбец таблицы. Это может произойти, например, если транзакция, вставившая строку, откатывается. См. nextval()
в Раздел 9.17 для получения подробной информации.
Чтобы вставить следующее значение последовательности в столбец serial
,
укажите, что столбцу serial
должно быть присвоено его значение по умолчанию. Это можно сделать
либо исключив столбец из списка столбцов в
операторе INSERT
, либо с помощью
ключевого слова DEFAULT
.
Имена типов serial
и serial4
эквивалентны: оба создают столбцы типа integer
. Имена типов bigserial
и serial8
работают таким же образом, за исключением того, что они создают столбец типа bigint
. bigserial
следует использовать, если вы предполагаете использование более чем 231 идентификаторов за период жизни таблицы. Имена типов smallserial
и serial2
также работают одинаково, за исключением того, что они создают столбец типа smallint
.
Последовательность, созданная для столбца типа serial
, автоматически удаляется при удалении владеющего столбца.
Вы можете удалить последовательность, не удаляя столбец, но это приведет к удалению выражения по умолчанию для столбца.