Перейти к содержимому

Double precision postgresql что это

  • автор:

Double precision postgresql что это

Числовые типы включают двух-, четырёх- и восьмибайтные целые, четырёх- и восьмибайтные числа с плавающей точкой, а также десятичные числа с задаваемой точностью. Все эти типы перечислены в Таблице 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 можно было сортировать и использовать в древовидных индексах, PostgreSQL считает, что значения 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 754 для двоичной арифметики с плавающей точкой (с одинарной и двойной точностью соответственно), в той мере, в какой его поддерживают процессор, операционная система и компилятор.

Неточность здесь выражается в том, что некоторые значения, которые нельзя преобразовать во внутренний формат, сохраняются приближённо, так что полученное значение может несколько отличаться от записанного. Управление подобными ошибками и их распространение в процессе вычислений является предметом изучения целого раздела математики и компьютерной науки, и здесь не рассматривается. Мы отметим только следующее:

Если вам нужна точность при хранении и вычислениях (например, для денежных сумм), используйте вместо этого тип numeric .

Если вы хотите выполнять с этими типами сложные вычисления, имеющие большую важность, тщательно изучите реализацию операций в вашей среде и особенно поведение в крайних случаях (бесконечность, антипереполнение).

На большинстве платформ тип real может сохранить значения в пределах от 1E-37 до 1E+37 с точностью не меньше 6 десятичных цифр. Тип double precision предлагает значения в диапазоне от 1E-307 до 1E+308 и с точностью не меньше 15 цифр. Попытка сохранить слишком большие или слишком маленькие значения приведёт к ошибке. Если точность вводимого числа слишком велика, оно будет округлено. При попытке сохранить число, близкое к 0, но непредставимое как отличное от 0, произойдёт ошибка антипереполнения.

Примечание

Параметр extra_float_digits определяет количество дополнительных значащих цифр при преобразовании значения с плавающей точкой в текст для вывода. Со значением по умолчанию ( 0 ) вывод будет одинаковым на всех платформах, поддерживаемых PostgreSQL. При его увеличении выводимое значение числа будет более точно представлять хранимое, но от этого может пострадать переносимость.

В дополнение к обычным числовым значениям типы с плавающей точкой могут содержать следующие специальные значения:

Они представляют особые значения, описанные в IEEE 754, соответственно « бесконечность » , « минус бесконечность » и « не число » . (На компьютерах, где арифметика с плавающей точкой не соответствует стандарту IEEE 754, эти значения, вероятно, не будут работать должным образом.) Записывая эти значения в виде констант в команде SQL, их нужно заключать в апострофы, например так: UPDATE table SET x = ‘Infinity’ . Регистр символов в этих строках не важен.

Примечание

Согласно IEEE754, NaN не должно считаться равным любому другому значению с плавающей точкой (в том числе и самому NaN ). Чтобы значения с плавающей точкой можно было сортировать и использовать в древовидных индексах, PostgreSQL считает, что значения NaN равны друг другу, и при этом больше любых числовых значений (не NaN ).

PostgreSQL также поддерживает форматы float и float( p ) , оговорённые в стандарте SQL, для указания неточных числовых типов. Здесь p определяет минимально допустимую точность в двоичных цифрах. PostgreSQL воспринимает запись от 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 следует использовать, если за всё время жизни таблицы планируется использовать больше чем 2 31 значений. И наконец, синонимами являются имена типов smallserial и serial2 , но они создают столбец smallint .

Последовательность, созданная для столбца serial , автоматически удаляется при удалении связанного столбца. Последовательность можно удалить и отдельно от столбца, но при этом также будет удалено определение значения по умолчанию.

Пред. Наверх След.
Глава 8. Типы данных Начало 8.2. Денежные типы

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 определяет количество десятичных цифр в дробной части, справа от десятичной точки, а точность — общее количество значимых цифр в числе, т. е. количество цифр по обе стороны десятичной точки. Например, число 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 можно было сортировать и использовать в древовидных индексах, PostgreSQL считает, что значения 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) вывод будет одинаковым на всех платформах, поддерживаемых PostgreSQL. При его увеличении выводимое значение числа будет более точно представлять хранимое, но от этого может пострадать переносимость.

В дополнение к обычным числовым значениям типы с плавающей точкой могут содержать следующие специальные значения:

Infinity
-Infinity
NaN Они представляют особые значения, описанные в IEEE 754, соответственно: «бесконечность» , «минус бесконечность» и «не число» . (Но компьютерах, где арифметика с плавающей точкой не соответствует стандарту IEEE 754, эти значения, вероятно, не будут работать должным образом.) Записывая эти значения в виде констант в команде SQL, их нужно заключать в апострофы, например так: UPDATE table SET x = 'Infinity'. Регистр символов в этих строках не важен.

Замечание: Согласно IEEE754, NaN не должно считаться равным любому другому значению с плавающей точкой (в том числе и самому NaN). Чтобы значения с плавающей точкой можно было сортировать и использовать в древовидных индексах, PostgreSQL считает, что значения NaN равны друг другу, и при этом больше любых числовых значений (не NaN).

PostgreSQL также поддерживает форматы float и float(p), оговорённые в стандарте SQL, для указания неточных числовых типов. Здесь p определяет минимально допустимую точность в двоичных цифрах. PostgreSQL воспринимает запись от 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 следует использовать, если за всё время жизни таблицы планируется использовать больше чем 2 31 значений. И наконец, синонимами являются имена типов smallserial и serial2, но они создают колонку smallint.

Последовательность, созданная для колонки serial, автоматически удаляется при удалении связанной колонки. Последовательность можно удалить и отдельно от колонки, но при этом также будет удалено определение значения по умолчанию.

Пред. Начало След.
Типы данных Уровень выше Денежные типы

Postgresql double или numeric?

numeric — Данный тип следует выбирать для хранения денежных сумм, а также в других случаях, когда требуется гарантировать точность вычислений.
Ни раз встречал программистов которые вместо numeric в PostgreSQL использовали double. Так же и в MySQL знакомый всегда использует double для тех же денег. Слышал что есть обсуждения насчет не точности double, но как вижу все его используют и не парятся. Хотелось бы спросить зачем нам нужен numeric тогда если есть real или double? Хотелось бы узнать зачем неточные типы когда есть точные?

Отслеживать
Mike Mclaren
задан 29 июн 2019 в 6:22
Mike Mclaren Mike Mclaren
835 12 12 серебряных знаков 24 24 бронзовых знака

Хотелось бы спросить зачем нам нужен numeric тогда если есть real или double? Вообще более естественным был бы обратный вопрос — нахрена неточные типы, когда есть точные. Но, судя по всему, Вы имеете ответ на этот вопрос.

29 июн 2019 в 8:37
@Akina я новичок поэтому и спрашиваю, хотелось бы узнать зачем неточные типы когда есть точные?
29 июн 2019 в 9:42
зачем неточные типы когда есть точные? А с ними математика быстрее.
30 июн 2019 в 17:00
@Akina то есть с точными типами операции работают быстрее и существенно возрастает скорость?
1 июл 2019 в 7:33
Наоборот. Точные типы медленнее. Но точнее.
1 июл 2019 в 7:47

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

melkij=> create temp table doublecalc (v double precision); CREATE TABLE melkij=> insert into doublecalc values (0.1), (0.2); INSERT 0 2 melkij=> select sum(v) = 0.3 from doublecalc ; ?column? ---------- f 

Что? Почему условие не выполняется? Потому что числа с плавающей запятой работают именно так (возможно вопрос необходимо вовсе закрыть как дубликат).

Справедливо и для postgresql и для mysql и для многих других. Вообще если вы назовёте float или double что-то не относящееся к IEEE 754 — вас не поймут. А всё основанное на IEEE 754 по своему определению является приближёнными вычислениями. И потому не может применяться в областях, где нужны точные вычисления. Ну и, разумеется, применяются и там тоже, а потом мучительно ищут ошибки. Людям свойственно делать глупости, но это не значит что эти глупости надо повторять.

Поэтому если вы хотите хранить деньги в числах с плавающей запятой — то вы или обосновываете что именно так необходимо сделать именно здесь или получаете больно по рукам при прохождении code review в любом приличном проекте.

PostgreSQL — Числовые типы

Числовые типы включают двух-, четырёх- и восьмибайтные целые, четырёх- и восьмибайтные числа с плавающей точкой, а также десятичные числа с задаваемой точностью.

Имя Размер Описание Диапазон
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

Для этих типов определён полный набор соответствующих арифметических операторов и функций.

Целочисленные типы

Типы smallint, integer и bigint хранят целые числа, то есть числа без дробной части, имеющие разные допустимые диапазоны. Попытка сохранить значение, выходящее за рамки диапазона, приведёт к ошибке.

Чаще всего используется тип integer, как наиболее сбалансированный выбор ширины диапазона, размера и быстродействия. Тип smallint обычно применяется, только когда крайне важно уменьшить размер данных на диске. Тип bigint предназначен для тех случаев, когда числа не умещаются в диапазон типа integer. В SQL определены только типы integer (или int), smallint и bigint. Имена типов int2, int4 и int8 выходят за рамки стандарта, хотя могут работать и в некоторых других СУБД.

Числа с произвольной точностью

Тип numeric позволяет хранить числа с очень большим количеством цифр. Он особенно рекомендуется для хранения денежных сумм и других величин, где важна точность. Вычисления с типом numeric дают точные результаты, где это возможно, например, при сложении, вычитании и умножении. Однако операции со значениями numeric выполняются гораздо медленнее, чем с целыми числами или с типами с плавающей точкой, описанными в следующем разделе.

Ниже мы используем следующие термины: Точность a numeric — это общее количество значащих цифр в целом числе, то есть количество цифр по обе стороны от десятичной точки. Масштаб а — это numeric количество десятичных цифр в дробной части справа от десятичной точки. Таким образом, число 23,5141 имеет точность 6 и масштаб 4. Можно считать, что целые числа имеют нулевой масштаб.

numeric Можно настроить как максимальную точность, так и максимальный масштаб столбца. Чтобы объявить столбец типа, numeric используйте синтаксис:

NUMERIC(precision, scale)

Точность должна быть положительной, шкала нулевой или положительной. В качестве альтернативы:

NUMERIC(precision)

выбирает масштаб 0. Указание:

NUMERIC

без какой-либо точности или масштаба создает « неограниченный числовой » столбец, в котором могут храниться числовые значения любой длины, вплоть до ограничений реализации. Столбец такого типа не будет приводить входные значения к какому-либо конкретному масштабу, тогда как numeric столбцы с объявленным масштабом будут приводить входные значения к этому масштабу. (Стандарт SQL требует шкалы по умолчанию, равной 0, т. е. приведения к целочисленной точности. Мы находим это немного бесполезным. Если вас беспокоит переносимость, всегда указывайте точность и масштаб явно.)

Если масштаб сохраняемого значения больше заявленного масштаба столбца, система округлит значение до указанного количества дробных цифр. Затем, если количество цифр слева от десятичной точки превышает заявленную точность минус заявленный масштаб, возникает ошибка.

Числовые значения физически хранятся без каких-либо дополнительных нулей в начале или в конце. Таким образом, заявленная точность и масштаб столбца являются максимальными, а не фиксированными выделениями. (В этом смысле 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 возведение в нулевую степень дает единицу.)

Типы 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)

Типы с плавающей запятой

Типы данных real и double precision являются неточными числовыми типами переменной точности. На всех поддерживаемых в настоящее время платформах эти типы являются реализациями стандарта IEEE 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 выбирает самый короткий и точный формат.

В дополнение к обычным числовым значениям типы с плавающей запятой имеют несколько специальных значений:
Infinity
-Infinity
NaN

Они представляют специальные значения IEEE 754 « бесконечность » , « отрицательная бесконечность » и « не число » соответственно. Записывая эти значения как константы в команде SQL, вы должны заключать их в кавычки, например UPDATE table SET x = ‘-Infinity’ . При вводе эти строки распознаются без учета регистра. В качестве альтернативы значения бесконечности могут быть записаны inf и -inf .

PostgreSQL также поддерживает нотации стандарта SQL float и для указания неточных числовых типов. Здесь указывает минимальную приемлемую точность в двоичных цифрах. PostgreSQL принимает в качестве выбора типа, а для выбора . Значения вне допустимого диапазона рисуют ошибку. без указания точности считается означающим . float(p)pfloat(1)float(24)realfloat(25)float(53)double precisionpfloatdouble precision

Серийные типы

Типы данных и не являются истинными типами smallserial , а являются просто удобными обозначениями для создания столбцов уникальных идентификаторов (аналогично свойству, поддерживаемому некоторыми другими базами данных). В текущей реализации указание: serialbigserialAUTO_INCREMENT

CREATE TABLE tablename ( colname SERIAL );
CREATE SEQUENCE tablename_colname_seq AS integer; CREATE TABLE tablename ( colname integer NOT NULL DEFAULT nextval('tablename_colname_seq') ); ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

Таким образом, мы создали целочисленный столбец и сделали так, чтобы его значения по умолчанию назначались из генератора последовательности. Ограничение NOT NULL применяется, чтобы гарантировать, что нулевое значение не может быть вставлено. (В большинстве случаев вы также захотите добавить ограничение UNIQUE или PRIMARY KEY , чтобы предотвратить случайную вставку повторяющихся значений, но это не происходит автоматически.) Наконец, последовательность помечается как « принадлежит » столбцу, поэтому она будет удалена . если столбец или таблица удалены.

Чтобы вставить следующее значение последовательности в serial столбец, укажите, что serial столбцу должно быть присвоено значение по умолчанию. Это можно сделать либо путем исключения столбца из списка столбцов в INSERT выписке, либо с помощью DEFAULT ключевого слова.

Имена типов serial и serial4 эквивалентны: оба создают integer столбцы. Имена типов bigserial и serial8 работают одинаково, за исключением того, что они создают bigint столбец. bigserial следует использовать, если предполагается использование более 2 31 идентификаторов за время существования таблицы. Имена типов smallserial и serial2 также работают одинаково, за исключением того, что они создают smallint столбец.

Последовательность, созданная для serial столбца, автоматически удаляется при удалении столбца-владельца. Вы можете удалить последовательность, не удаляя столбец, но это приведет к удалению выражения столбца по умолчанию.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *