Документация по PostgreSQL 8.2devel | ||||
---|---|---|---|---|
Prev | Fast Backward | Chapter 8. Типы данных | Fast Forward | Next |
Числовые типы представлены двух, четырёх и восьми байтовыми целыми числами, четырёх и восьми байтовыми числами с плавающей точкой и числами с выбираемой точностью (количеством знаков после точки). В Table 8-2 перечислены доступные типы.
Table 8-2. Числовые типы
Имя | Размер хранения | Описание | Диапазон |
---|---|---|---|
smallint | 2 байта | целые числа малого диапазона | от -32768 до +32767 |
integer | 4 байта | обычные целые числа | от -2147483648 до +2147483647 |
bigint | 8 байт | целые числа большого диапазона | от -9223372036854775808 до 9223372036854775807 |
decimal | переменный | числа с точностью, указываемой пользователем, точное число | без ограничений |
numeric | переменный | числа с точностью, указываемой пользователем, точное число | без ограничений |
real | 4 байта | переменная точность, неточное число | точность 6 десятичных разрядов |
double precision | 8 байт | переменная точность, неточное число | точность 15 десятичных разрядов |
serial | 4 байта | целое число с автоувеличением | от 1 до 2147483647 |
bigserial | 8 байт | большое целое число с автоувеличением | от 1 до 9223372036854775807 |
Синтаксис констант для числовых типов описывается в Section 4.1.2. Числовые типы имеют полный набор соответствующих арифметических операторов и функций. Подробности смотрите в Chapter 9. Следующие разделы детально описывают перечисленные выше типы.
Типы smallint, integer и bigint хранят обыкновенные числа, т.е. числа без дробной части, но разных диапазонов. Попытки сохранить значения, которые выходят за рамки разрешённого диапазона приведут к ошибке.
Тип integer является наиболее удачным выбором, потому что он предлагает лучший баланс между диапазоном хранимых значений, размером хранимых значений и производительностью. Тип smallint обычно используется только в случаях, когда необходимо крайне рациональное использование дискового пространства. Тип bigint должен использоваться только если не хватает диапазона типа integer, потому что работа с последним осуществляется существенно быстрее.
Тип bigint на некоторых платформах может функционировать неправильно, так как он зависит от поддержки компилятором восьмибайтовых целых чисел. На машинах, где такой поддержки нет, bigint работает также как integer (но по прежнему использует восемь байт для хранения). Однако, нам неизвестны какие-либо значимые платформы, где по факту это и происходит.
SQL определяет только целочисленные типы integer (или int) и smallint. Тип bigint и имена типов int2, int4 и int8 являются расширениями, которые работают и в некоторых других SQL СУБД.
Тип данных numeric может хранить числа с точностью до 1000 знаков после точки и с этим типом могут выполняться точные вычисления. Использование этого типа собенно рекомендуется для хранения денежных значений и других величин, для которых требуется точность. Однако, для типа numeric, работа с арифметическими значениями осуществляется очень медленно по сравнению с целочисленными типами или типами с плавающей точкой, о которых рассказывается в следущем разделе.
Далее мы будем использовать следующие термины: масштаб(scale) типа numeric — это количество десятичных разрядов в дробной части, справа от десятичной точки. Точность (precision) типа numeric — это общее количество значимых разрядов во всём числе, т.е. количество разрядов по обе стороны от десятичной точки. Таким образом, число 23.5141 имеет точность 6 и масштаб 4. Целые числа могут быть представлены с использованием масштаба ноль.
Для колонки с типом numeric можно настроить и максимальную точность и максимальный масштаб. Для определения колонки типа numeric используйте синтаксис:
NUMERIC(точность, масштаб)
Точность должна быть положительным значением, масштаб должен быть либо положительным значением либо нулём. Можно также использовать и такой синтаксис:
NUMERIC(точность)
который обусловливает значение масштаба 0. Если задать
NUMERIC
без значений точности и масштаба, будет создана колонка, в которой можно хранить значения типа numeric с любыми точностью и масштабом, ограниченными только реализованным в СУБД пределом точности. Колонка такого вида будет приводить вводимые значения к любому отдельному масштабу, в то время как колонки типа numeric с заданным значением масштаба будут приводить вводимые значениям к этому масштабу. (Стандарт SQL требует установки по умолчанию масштаба 0, т.е. приведение к целому числу. Мы находим это несколько бесполезным. Если вас заботит переносимость, всегда явно указывайте точность и масштаб).
Если масштаб какого-либо значения больше, чем заявленный масштаб колонки, то система округлит это значение до указанного количества дробных разрядов. Затем, если количество разрядов слева от десятичной точки превышает заявленную точность минус заявленный масштаб, будет выдано сообщение об ошибке.
Значения numeric физически хранятся без каких-либо дополнительных нулей вначале или в конце. Следовательно, заявленная точность и масштаб колонки являются максимально возможными, но размер хранения для них выделяется нефиксированный. (В этом смысле тип numeric больше похож на тип varchar(n), чем на тип char(n).) Фактически требования, предъявляемые к хранению — это два байта для каждой группы из четырёх десятичных разрядов, плюс ещё восемь байт.
В дополнение к обычным числовым значениям, тип numeric позволяет хранить специальное значение NaN, которое означает "not-a-number (не число)". Любые операции над NaN в качестве результата дают другое значение NaN. Когда это значение пищется как константа в команде SQL, вы должны заключить его в одинарные кавычки, например UPDATE table SET x = 'NaN'. При вводе, строка NaN разпознаётся независимо от регистра букв.
Типы decimal и numeric эквивалентны. Оба типа являются частью стандарта SQL.
Типы данных real и double precision являются неточными числовыми типами с переменной точностью. На практике, эти типы обычно реализуются по стандарту IEEE Standard 754 для Двоичной Арифметики с Плавающей Точкой (соответственно одинарной и двойной точности), согласно поддержке этих типов, процессором, операционной системой и компилятором.
Слово "неточный", применительно к этим типам означает, что некоторые значения не могут быть точно преобразованы во внутренний формат этих типов и поэтому они хранятся как приблизительные значения, так что если сохранить одно из таких значений и затем вывести его обратно, то можно увидеть незначительные отличия. Управление такими ошибками и то как они разрастаются при вычислениях — это тема целой ветки математики и компьютерной науки. Поэтому здесь это рассказываться не будет, за исключением следующих моментов:
Если требуется точное хранение и вычисление значений (таких как денежные величины), используйте вместо данных типов, тип numeric.
Если вы хотите выполнять сложные вычисления с этими типами для каких-либо важных целей, особенное если вы надеетесь на определённое поведение в граничных моментах (бесконечность, переполнение) вы должны реализовывать такие вычисления осторожно.
Сравнение двух значений с плавающей точкой на равенство может работать, а может и не работать так как вы ожидаете.
На большистве платформ, тип real имеет диапазон как минимум от 1E-37 до 1E+37 с точностью по меньшей мере в 6 десятичных разрядов. Тип double precision обычно имеет диапазон от 1E-307 до 1E+308 с точностью по меньшей мере в 15 разрядов. Значения, которые слишком велики или слишком малы приведут к ошибке. Если точность вводимых чисел слишком велика, возможно округление. Числа слишком приближающиеся к нулю, которые не могут быть представлены как отличные от нуля приведут к ошибке переполнения.
В дополнение к обычным числовым значениям, типы с плавающей точкой имеют некоторые специальные значения:
Infinity
-Infinity
NaN
PostgreSQL также поддерживает стандартную нотацию float и float(p) для задания неточных числовых типов. Здесь p указывает минимально доступную точность в двоичных разрядах. PostgreSQL принимает значения от float(1) до float(24) как тип real и значения от float(25) до float(53) как double precision. Значения p выходящие за этот допустимый диапазон приведут к ошибке. Указание float без точности означает double precision.
Note: До версии PostgreSQL 7.4, точность у float(p) означала количество десятичных разрядов. Для соответствия стандарту SQL, который говорит, что точность измеряется в двоичных разрядах — это было исправлено. Для типов real и double precision в мантиссе соответственно содержится 24 и 53 бит, что соответствует стандарту IEEE на реализацию чисел с плавающей точкой. На платформах не соответствующих стандарту IEEE, количество бит может быть меньше, но для простоты, на всех платформах используется одни и те же диапазоны p.
Типы данных serial и bigserial не являются полноценными типами, а просто являются удобной нотацией для установки колонок, которые играют роль уникального идентификатора (свойство сходное с AUTO_INCREMENT поддерживается и некоторыми другими СУБД). В текущей реализации, конструкция
CREATE TABLE имя_таблицы ( имя_колонки SERIAL );
эквивалента конструкции:
CREATE SEQUENCE имя_таблицы_имя_колонки_seq; CREATE TABLE имя_таблицы ( имя_колонки integer DEFAULT nextval('имя_таблицы_имя_колонки_seq') NOT NULL );
Таким образом, мы создали колонку с типом integer и назначили для неё значения по умолчанию, которые получаются с помощью генератора последовательности. Ограничение NOT NULL предназначено для того, чтобы иметь уверенность в том, что в колонке не могут быть значения null. В большинстве случаев вам также понадобится применить ограничения UNIQUE или PRIMARY KEY, чтобы предотвратить появление в колонке дублированных значений. Эти ограничения не устанавливаются автоматически.
Note: До версии PostgreSQL 7.3, тип serial неявно включал ограничение UNIQUE. Но больше этого нет. Если вы хотите ограничение уникальности или первичного ключа для колонки с типом serial, вы должны сделать его вручную, точно также как и для других типов данных.
Чтобы вставить следующее значение последовательности в колонку с типом serial, укажите, что в колонку с типом serial вставляется значение по умолчанию для этой колонки. Это можно сделать либо не указывая колонку с списке колонок в операторе INSERT, либо используя ключевое слово DEFAULT.
Типы с именами serial и serial4 эквиваленты: оба создают колнки с типом integer. Точно также и типы с именами bigserial и serial8, за исключением того, что они создают колнки с типом bigint. Тип bigserial должен использоваться если вы ожидаете совместное использование более чем 231 индентификаторов в одной таблице.
Последовательность, создаваемая для колонки serial
автоматически удаляется, когда удаляется колонка для которой
генерируется эта последовательности и не удаляется в других
случаях. (Это не так в версиях PostgreSQL
до 7.3. Заметим, что это автоматическое удаление не будет работать
для последовательности, созданной загруженным дампом от базы
данных версий до 7.3; такой файл дампа не содержит информацию,
которая необходима для создания соответствующей зависимой связи.)
Таким образом, зависимость между последовательностью и колонкой
может быть создана только для самой колонки serial.
Если любые другие колонки ссылаются на эту же последовательность
(предположим с помощью вызова функции nextval
вручную), то они будут сломаны, если эта последовательность будет
удалена. Использование последовательности колонки serial
в такой манере считается плохим тоном; если вы хотите задействовать
несколько колонок от одного генератора последовательности,
создайте эту последовательность как независимый объект.