Числовые типы включают двух-, четырех- и восьмибайтовые целые числа, четырех- и восьмибайтовые числа с плавающей точкой, а также десятичные числа с настраиваемой точностью. Таблица 2.5.2 содержит список доступных типов.
Таблица 2.5.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 |
Синтаксис констант для числовых типов описан в Раздел 2.1.1.2. Для числовых типов доступен полный набор соответствующих арифметических операторов и функций. Обратитесь к Глава 2.6 для получения дополнительной информации. В следующих разделах эти типы описаны подробно.
Типы smallint, integer, и
bigint позволяют хранить целые числа (числа без дробной части) в различных диапазонах. Попытка сохранения значения вне допустимого диапазона приведет к ошибке.
Тип integer является стандартным выбором, так как он обеспечивает оптимальный баланс между диапазоном значений, размером хранения и производительностью. smallint тип обычно используется только при жесткой экономии дискового пространства. bigint тип предназначен для использования в тех случаях, когда диапазона типа integer недостаточно.
SQL определяет только целочисленные типы
integer (или int),
smallint, и bigint. Названия
типов int2, int4, и
int8 являются расширениями, которые также используются в некоторых
других SQL системах баз данных.
Тип numeric могут хранить числа с очень большим количеством цифр. Данный тип особенно рекомендуется для хранения денежных сумм и других величин, требующих точности. Вычисления со numeric значениями дают точные
результаты, где это возможно (например, сложение, вычитание, умножение).
Однако вычисления со numeric значениями выполняются очень медленно по сравнению с целочисленными типами или типами с плавающей точкой, описанными в следующем разделе.
Ниже используются следующие термины:
точность для numeric
— это общее количество значимых цифр во всём числе, то есть количество цифр по обе стороны от десятичной точки. Параметр масштаб для numeric — это количество десятичных цифр в дробной части, расположенных справа от десятичной точки. Таким образом, число 23.5141 имеет точность 6 и масштаб 4. Для целых чисел масштаб считается равным нулю.
Как максимальная точность, так и максимальный масштаб
numeric столбца могут быть
сконфигурированы. Для объявления столбца с типом данных numeric используйте
следующий синтаксис:
NUMERIC(точность,масштаб)
Параметр точности должен быть положительным, тогда как масштаб может быть как положительным, так и отрицательным (см. ниже). Кроме того:
NUMERIC(точность)
устанавливает масштаб 0. Указание:
NUMERIC
без указания параметров точности и масштаба создает «неограниченный
числовой» столбец, в котором могут храниться числовые значения любой длины в пределах ограничений реализации. Столбец такого типа не будет приводить входные значения к определенному масштабу, в то время как
numeric для столбцов с объявленным масштабом обеспечивает приведение входных значений к этому масштабу. (Стандарт SQL стандарт
требует использования масштаба 0 по умолчанию, то есть приведения к целочисленной
точности. Мы считаем эту особенность малополезной. Если для вас важна переносимость, всегда указывайте точность и масштаб явно.)
Максимальное значение точности, которое может быть явно указано в numeric объявлении типа, составляет 1000. Столбец без numeric ограничений подчиняется лимитам, описанным в Таблица 2.5.2.
Если масштаб сохраняемого значения больше объявленного масштаба столбца, система округляет значение до указанного количества десятичных знаков. Затем, если количество цифр слева от десятичной точки превышает разность между объявленной точностью и объявленным масштабом, возникает ошибка. Например, столбец, объявленный как
NUMERIC(3, 1)
округляет значения до 1 десятичного знака и позволяет хранить значения в диапазоне от -99.9 до 99.9 включительно.
Начиная с Digital Q.DataBase версии 15, допускается
объявление numeric столбца с отрицательным масштабом. В этом случае значения будут округляться слева от десятичной точки. Параметр точности по-прежнему представляет максимальное количество неокругленных цифр. Таким образом, столбец, объявленный как
NUMERIC(2, -3)
будет округлять значения до ближайшей тысячи и может хранить значения в диапазоне от -99000 до 99000 включительно. Также допускается объявление масштаба, превышающего объявленную точность. Такой столбец может содержать только дробные значения, при этом количество нулевых разрядов непосредственно справа от десятичной точки должно быть не меньше разности между объявленным масштабом и объявленной точностью. Например, столбец, объявленный как
NUMERIC(3, 5)
будет округлять значения до 5 десятичных знаков и может хранить значения в диапазоне от -0.00999 до 0.00999 включительно.
Digital Q.DataBase допускает использование в
numeric объявлении типа любого значения в диапазоне
от -1000 до 1000. Однако SQL стандарт требует, чтобы параметр масштаба находился в диапазоне от 0 до точность. Использование масштабов вне этого диапазона может привести к потере переносимости на другие системы баз данных.
Числовые значения физически хранятся без лишних ведущих или завершающих нулей. Таким образом, объявленные точность и масштаб столбца
являются максимальными значениями, а не фиксированным объемом памяти. (В этом смысле numeric
тип более сопоставим с varchar(
нежели с n)char(.) Фактический объем памяти для хранения составляет два байта на каждую группу из четырех десятичных цифр, плюс от трех до восьми байт накладных расходов.
n)
Помимо обычных числовых значений, данный numeric тип
поддерживает несколько специальных значений:
Infinity
-Infinity
NaN
Эти значения адаптированы из стандарта IEEE 754 и представляют
«infinity», «отрицательную бесконечность», и
«не число (NaN)»соответственно. При записи этих значений
в виде констант в SQL-команде их необходимо заключать в кавычки,
например UPDATE table SET x = '-Infinity'.
При вводе эти строки распознаются независимо от регистра.
Значения бесконечности также могут записываться как inf
и -inf.
Значения бесконечности ведут себя в соответствии с математическими правилами. Например, Infinity плюс любое конечное значение равно
Infinity, равно как и Infinity
плюс Infinity; но Infinity
минус Infinity дает NaN (не число), так как эта операция не имеет определенной интерпретации. Обратите внимание, что значение бесконечности (infinity) может храниться только в столбце numeric
без ограничений, поскольку оно условно превышает любой предел конечной точности.
Значение NaN (не число) используется для представления неопределенных результатов вычислений. В общем случае любая операция с NaN входным параметром возвращает значение NaN. Единственным исключением являются случаи, когда другие входные параметры операции таковы, что был бы получен тот же результат, если бы значение NaN было
заменено любым конечным или бесконечным числовым значением; в этом случае данный результат
используется и для NaN также. (Примером этого
принципа является то, что NaN в нулевой степени
дает единицу.)
В большинстве реализаций «не число (NaN)» концепции
NaN не считается равным любому другому числовому
значению (включая NaN). Чтобы обеспечить
numeric сортировку значений и их использование в древовидных индексах, Digital Q.DataBase обрабатывает NaN
значения как равные и превосходящие любые не-NaN
значения.
Типы decimal и numeric являются
эквивалентными. Оба типа входят в SQL
стандарт.
При округлении значений тип numeric округляет средние значения (tie) в сторону от нуля, в то время как (на большинстве систем) типы 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 строк)
Типы данных real и double precision являются
неточными числовыми типами с переменной точностью. На всех поддерживаемых в настоящее время
платформах эти типы представляют собой реализации IEEE
стандарта 754 для двоичной арифметики с плавающей точкой (одинарной и двойной точности соответственно) в той мере, в какой это поддерживается процессором, операционной системой и компилятором.
Понятие «неточные» означает, что некоторые значения невозможно точно преобразовать во внутренний формат, в результате чего они сохраняются в виде приближений. Таким образом, операции сохранения и извлечения значения могут выявить небольшие расхождения. Вопросы управления данными ошибками и их распространения в вычислениях рассматриваются в рамках отдельных разделов математики и информатики и здесь не обсуждаются, за исключением следующих моментов:
Если требуется обеспечить точность хранения и вычислений (например, для
денежных сумм), используйте numeric тип.
При необходимости выполнения сложных вычислений с использованием данных типов для решения критически важных задач, особенно в случаях зависимости от определенного поведения в граничных условиях (бесконечность, потеря значимости), следует тщательно проанализировать особенности реализации.
Сравнение двух значений с плавающей точкой на равенство может не всегда давать ожидаемый результат.
На всех поддерживаемых в настоящее время платформах real тип имеет диапазон значений примерно от 1E-37 до 1E+37 с точностью не менее 6 десятичных разрядов. double precision тип имеет диапазон примерно от 1E-307 до 1E+308 с точностью не менее 15 цифр. Значения, которые
слишком велики или слишком малы, вызывают ошибку. Если точность входного числа слишком высока,
может быть выполнено округление. Числа, слишком близкие к нулю и неотличимые от него, вызывают ошибку антипереполнения (underflow).
По умолчанию значения с плавающей точкой выводятся в текстовом виде в их кратчайшем точном десятичном представлении; получаемое десятичное значение ближе к истинному сохраненному двоичному значению, чем к любому другому значению, представимому с той же двоичной точностью. (Однако выводимое значение в настоящее время никогда не располагается точно посередине между двумя
представимыми значениями; это позволяет избежать широко распространенной ошибки, при которой
процедуры ввода некорректно применяют правило округления к ближайшему четному значению.) Это значение будет
содержать не более 17 значащих десятичных цифр для float8
значений и не более чем 9 цифр для float4 значений.
Данный формат вывода минимальной точности (shortest-precise) генерируется значительно быстрее, чем традиционный формат с округлением.
Для обеспечения совместимости с выводом, сформированным в предыдущих версиях Digital Q.DataBase, а также для обеспечения возможности снижения точности вывода, параметр extra_float_digits
может использоваться для выбора вывода десятичных чисел с округлением. Установка значения 0 восстанавливает принятое ранее по умолчанию округление значения до 6 (для float4) или 15 (для float8) значимых десятичных цифр. Установка отрицательного значения приводит к дальнейшему сокращению количества цифр; например, значение -2 округляет вывод до 4 или 13 цифр соответственно.
Любое значение параметра extra_float_digits большее 0, активирует формат вывода минимальной точности (shortest-precise).
Приложениям, требующим получения точных значений, исторически приходилось устанавливать параметр extra_float_digits в значение 3 для их получения. Для обеспечения максимальной совместимости между версиями рекомендуется придерживаться этой практики и далее.
Помимо обычных числовых значений, типы с плавающей точкой имеют несколько специальных значений:
Infinity
-Infinity
NaN
Они представляют собой специальные значения стандарта IEEE 754
«infinity», «отрицательную бесконечность», и
«не число (NaN)»соответственно. При записи этих значений
в виде констант в SQL-команде их необходимо заключать в кавычки,
например UPDATE table SET x = '-Infinity'. При вводе эти строки распознаются без учета регистра. Значения бесконечности также могут записываться как inf
и -inf.
Стандарт IEEE 754 определяет, что NaN не должно быть равно
любому другому значению с плавающей точкой (включая NaN).
Чтобы значения с плавающей точкой можно было сортировать и использовать
в древовидных индексах, Digital Q.DataBase рассматривает
NaN значения как равные и большие, чем все
значения, отличные отNaN значений.
Digital Q.DataBase также поддерживает нотации стандарта SQL float и
float( для указания
неточных числовых типов. Здесь параметр p)p задает
минимально допустимую точность в двоичных разрядах.
Digital Q.DataBase принимает
float(1) по float(24) эквивалентно выбору
real типа, тогда как
float(25) по float(53) выбирает
double precision. Значения p
вне допустимого диапазона приводят к ошибке.
float без указания точности интерпретируется как
double precision.
В данном разделе описывается специфичный для Digital Q.DataBase способ создания столбца с автоинкрементом. Другой способ заключается в использовании функции столбцов идентификации (identity columns) согласно стандарту SQL, описанной в Раздел 2.2.3.
Типы данных smallserial, serial и
bigserial не являются полноценными типами, а представляют собой лишь
удобную форму записи для создания столбцов с уникальными идентификаторами
(аналогично свойству AUTO_INCREMENT свойство
поддерживается некоторыми другими базами данных). В текущей
реализации указание:
CREATE TABLEtablename(colnameSERIAL );
эквивалентно следующей записи:
CREATE SEQUENCEtablename_colname_seq AS integer; CREATE TABLEtablename(colnameinteger NOT NULL DEFAULT nextval('tablename_colname_seq') ); ALTER SEQUENCEtablename_colname_seq OWNED BYtablename.colname;
Таким образом, создается целочисленный столбец, значения которого по умолчанию формируются генератором последовательности. NOT NULL
ограничение применяется для исключения возможности вставки неопределенного значения (null). (В большинстве случаев также целесообразно добавить
UNIQUE или PRIMARY KEY ограничение для предотвращения случайной вставки дублирующихся значений, но это не происходит автоматически). Наконец, последовательность помечается как «связанная со»
столбцом, чтобы она была удалена при удалении столбца или таблицы.
Поскольку smallserial, serial и
bigserial реализованы с помощью последовательностей, могут
возникать «дыры» или пропуски в последовательности значений, появляющихся в
столбце, даже если строки никогда не удалялись. Значение, выделенное
из последовательности, всё равно считается «использованным», даже если строка, содержащая это
значение, так и не была успешно вставлена в столбец таблицы. Это
может произойти, например, в случае отката транзакции вставки.
См. описание функции nextval() в Раздел 2.6.17
для получения подробных сведений.
Для вставки следующего значения последовательности в serial
столбец укажите, что serial
столбцу должно быть присвоено его значение по умолчанию. Это можно сделать
либо путем исключения столбца из списка столбцов в
команде INSERT либо с помощью
ключевого слова DEFAULT key word.
Названия типов serial и serial4 являются
эквивалентными: оба создают integer столбцы. Названия
типов bigserial и serial8 работают
аналогичным образом, за исключением того, что они создают bigint
столбец. bigserial следует использовать, если предполагается
использование более 231 идентификаторов за все время существования таблицы. Названия типов smallserial и
serial2 также работают аналогичным образом, за исключением того, что они
создают smallint столбец.
Последовательность, созданная для serial столбца, удаляется автоматически при удалении соответствующего столбца. Можно удалить последовательность, не удаляя сам столбец, но это приведет к принудительному удалению выражения значения по умолчанию для этого столбца.