On this page
8.1. 数字类型
数值类型包括 2 字节,4 字节和 8 字节整数,4 字节和 8 字节浮点数以及可选精度的小数。 Table 8.2列出了可用的类型。
表 8.2. 数值类型
Name | Storage Size | Description | Range |
---|---|---|---|
smallint |
2 bytes | small-range integer | -32768 至 32767 |
integer |
4 bytes | 整数的典型选择 | -2147483648 至 2147483647 |
bigint |
8 bytes | large-range integer | -9223372036854775808 至 9223372036854775807 |
decimal |
variable | 用户指定的精确度 | 小数点前最多 131072 位数字;小数点后最多 16383 位 |
numeric |
variable | 用户指定的精确度 | 小数点前最多 131072 位数字;小数点后最多 16383 位 |
real |
4 bytes | variable-precision, inexact | 6 十进制数字精度 |
double precision |
8 bytes | variable-precision, inexact | 15 十进制数字精度 |
smallserial |
2 bytes | 小自动递增整数 | 1 至 32767 |
serial |
4 bytes | autoincrementing integer | 1 至 2147483647 |
bigserial |
8 bytes | 大的自动递增整数 | 1 至 9223372036854775807 |
用于数字类型的常量的语法在Section 4.1.2中描述。数值类型具有一整套对应的算术运算符和函数。有关更多信息,请参考Chapter 9。以下各节详细介绍了这些类型。
8 .1.1. 整数类型
类型smallint
,integer
和bigint
存储整数,即没有小数部分的数字,其范围是各种。尝试存储超出允许范围的值将导致错误。
integer
类型是常见的选择,因为它在范围,存储大小和性能之间提供了最佳的平衡。通常仅在磁盘空间有限的情况下使用smallint
类型。 bigint
类型设计为在integer
类型的范围不足时使用。
SQL 仅指定整数类型integer
(或int
),smallint
和bigint
。类型名称int2
,int4
和int8
是 extensions,其他一些 SQL 数据库系统也使用这些 extensions。
8 .1.2. 任意精度数
类型numeric
可以存储数量非常大的数字。特别建议在需要精确度的情况下存储货币金额和其他数量。带有numeric
值的计算会在可能的情况下产生准确的结果,例如加,减,乘。但是,与整数类型或下一节中描述的浮点类型相比,对numeric
值的计算非常慢。
我们在下面使用以下术语:numeric
的* precision 是整数中有效数字的总计数,即小数点两侧的位数。 numeric
的 scale *是小数点右边小数部分中小数位数的计数。因此,数字 23.5141 的精度为 6,小数位数为 4.可以将整数视为小数位数为零。
可以配置numeric
列的最大精度和最大比例。要声明类型numeric
的列,请使用以下语法:
NUMERIC(precision, scale)
精度必须为正,小数位数为零或正。或者:
NUMERIC(precision)
选择 0 的小数位数。
NUMERIC
没有任何精度或小数位数的列会创建一列,其中可以存储任何精度和小数位数的数值,但不超过精度的实施限制。这种类型的列不会将 Importing 值强制转换为任何特定的比例,而声明了比例的numeric
列会将 Importing 值强制转换为该比例。 (SQL 标准要求默认小数位数为 0,即强制转换为整数精度.我们发现这有点用.如果您担心可移植性,请始终明确指定精度和小数位数.)
Note
在类型声明中明确指定的最大允许精度为 1000;没有指定精度的NUMERIC
受Table 8.2中所述的限制。
如果要存储的值的小数位数大于该列的声明的小数位数,则系统会将值四舍五入到指定的小数位数。然后,如果小数点左边的位数超过了声明的精度减去声明的小数位数,则会引发错误。
数值是物理存储的,没有任何额外的前导或尾随零。因此,声明的列的精度和小数位数是最大值,而不是固定分配。 (从这种意义上讲,numeric
类型更类似于varchar(n)
而不是char(n)
.)实际的存储要求是每组四个十进制数字的两个字节,外加三至八个字节的开销。
除普通数值外,numeric
类型还允许特殊值NaN
表示“非数字”。对NaN
进行的任何操作都会产生另一个NaN
。在 SQL 命令中将此值写为常量时,必须在其两边加上引号,例如UPDATE table SET x = 'NaN'
。Importing 时,以不区分大小写的方式识别字符串NaN
。
Note
在“非数字”概念的大多数实现中,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 的实现(分别为单精度和双精度),只要底层处理器,os 和编译器支持它即可。
不精确意味着某些值无法完全转换为内部格式,无法以近似值存储,因此存储和检索值可能会出现细微的差异。Management 这些错误及其在计算中的传播方式是 math 和计算机科学整个分支的主题,在以下内容中将不进行讨论:
如果您需要精确的存储和计算(例如,金额),请使用
numeric
类型。如果您想对这些重要的事情使用这些类型进行复杂的计算,特别是如果您在边界情况下(无穷大,下溢)依赖某些行为,则应仔细评估实现。
比较两个浮点值的相等性可能并不总是按预期进行。
在大多数平台上,real
类型的范围至少为 1E-37 到 1E 37,精度至少为 6 个十进制数字。 double precision
类型的范围通常在 1E-307 到 1E 308 之间,精度至少为 15 位数字。太大或太小的值都会导致错误。如果 Importing 数字的精度过高,则可能会四舍五入。太接近零且无法表示为不同于零的数字将导致下溢错误。
Note
extra_float_digits设置控制将浮点值转换为文本以输出时包含的额外有效数字的数量。默认值为0
,在 PostgreSQL 支持的每个平台上输出都是相同的。增加它会产生更准确地表示存储值的输出,但可能无法携带。
除普通数值外,浮点类型还具有几个特殊值:
Infinity
-Infinity
NaN
它们分别表示 IEEE 754 特殊值“无穷大”,“负无穷大”和“非数字”。 (在浮点运算不遵循 IEEE 754 的计算机上,这些值可能无法按预期方式工作.)当在 SQL 命令中将这些值写为常量时,必须在其两边加上引号,例如UPDATE table SET x = '-Infinity'
。Importing 时,这些字符串以不区分大小写的方式识别。
Note
IEEE754 指定NaN
不应等于任何其他浮点值(包括NaN
)。为了允许对浮点值进行排序并在基于树的索引中使用,PostgreSQL 将NaN
值视为相等,并且大于所有非NaN
值。
PostgreSQL 还支持用于指定不精确数字类型的 SQL 标准符号float
和float(p)
。在这里,* p
以二进制*数字指定最小可接受精度。 PostgreSQL 接受float(1)
到float(24)
作为选择real
类型,而float(25)
到float(53)
选择double precision
。 * p
*的值超出允许范围会引发错误。未指定精度的float
表示double precision
。
Note
real
和double precision
分别在尾数中分别具有 24 位和 53 位的假设对于 IEEE 标准浮点实现是正确的。在非 IEEE 平台上,可能会有些偏离,但为简单起见,在所有平台上都使用相同的* p
*范围。
8 .1.4. 序列类型
Note
本节介绍了 PostgreSQL 特定的创建自动增量列的方法。另一种方法是使用CREATE TABLE中描述的 SQL 标准身份列功能。
数据类型smallserial
,serial
和bigserial
不是真实类型,而仅仅是创建唯一标识符列的方便符号(类似于某些其他数据库支持的AUTO_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
约束,以防止意外插入重复的值,但这不是自动的.)最后,该序列被标记为列的“所有者”,因此它将如果列或表被删除,则被删除。
Note
因为smallserial
,serial
和bigserial
是使用序列实现的,所以即使没有行被删除,列中出现的值序列中也可能存在“空洞”或间隙。即使从未成功将包含该值的行插入表列,也仍会“用完”从序列分配的值。例如,如果插入事务回滚,则可能会发生这种情况。有关详情,请参见Section 9.16中的nextval()
。
要将序列的下一个值插入serial
列,请指定应为serial
列分配其默认值。可以通过从INSERT
语句的列列表中排除该列,或使用DEFAULT
关键字来完成此操作。
类型名称serial
和serial4
是等效的:都创建integer
列。类型名称bigserial
和serial8
以相同的方式工作,除了它们创建bigint
列。如果预计在表的生命周期内使用超过 231 个标识符,则应使用bigserial
。类型名称smallserial
和serial2
的工作方式相同,但它们创建的是smallint
列。
删除拥有的列时,将自动删除为serial
列创建的序列。您可以删除序列而不删除列,但是这将强制删除列默认表达式。