serial
自增四字节整数
当前查看 PostgreSQL 18.6。
PG10–20 核心源码清单。类型转换与操作符类列出源码显式声明的关系;缺少记录不能排除通过其他机制进行转换或使用索引。
定义
SQL 名称与别名: serial4
自增四字节整数
serial
- 对象边界
- SQL 便捷写法;没有对应的 pg_type 行
中文手册
阅读来源定义
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 的精度是整个数值的有效数字总数,即小数点两侧数字的总位数;小数位数是小数点右侧小数部分的十进制数字位数。例如,23.5141 的精度为 6,小数位数为 4。整数可以视为小数位数为零。
numeric 列的最大精度和最大小数位数都可以配置。声明 numeric 类型列时使用以下语法:
NUMERIC(precision,scale)
精度必须为正数,小数位数可以为正数或负数,见下文。也可以写为:
NUMERIC(precision)
选择小数位数为 0。指定:
NUMERIC
不指定精度或小数位数时,将创建一个“不受约束的 numeric”列,可存储任意长度的数值,但仍受实现上限约束。这类列不会将输入值强制转换为特定的小数位数,而声明了小数位数的 numeric 列会强制转换为该位数。(SQL 标准要求默认小数位数为 0,即强制采用整数精度。我们认为这样不太实用。如果需要兼容其他数据库,应始终显式指定精度和小数位数。)
注意
numeric 类型声明可显式指定的最大精度为 1000。未限定精度的 numeric 列受表 8.2 所述限制约束。
如果待存储值的小数位数大于列声明的小数位数,系统会将该值舍入到指定的小数位数。随后,如果小数点左侧的位数超过声明精度减去声明小数位数的结果,就会报错。例如,声明为下列形式的列:
NUMERIC(3, 1)
会将值舍入到 1 位小数,并可存储 -99.9 至 99.9 之间的值,包含两端。
从 PostgreSQL 15 开始,允许声明小数位数为负的 numeric 列。此时,数值会在小数点左侧进行舍入。精度仍表示未被舍入部分的最大位数。因此,声明为下列形式的列:
NUMERIC(2, -3)
会将值舍入到最接近的千位,并可存储 -99000 至 99000 之间的值,包含两端。还允许声明大于精度的小数位数。这样的列只能保存小数值,并要求小数点右侧紧接的零的位数,至少为声明的小数位数减去声明的精度。例如,声明为下列形式的列:
NUMERIC(3, 5)
会将值舍入到 5 位小数,并可存储 -0.00999 至 0.00999 之间的值,包含两端。
注意
PostgreSQL 允许 numeric 类型声明中的小数位数为 -1000 到 1000 之间的任意值。但 SQL 标准要求它介于 0 和精度之间。使用此范围以外的小数位数,可能无法移植到其他数据库系统。
numeric 值在物理存储时不会保留多余的前导零或尾随零。因此,列声明的精度与小数位数是最大限制,而非固定分配的空间。(从这一点看,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 的零次方为一。)
注意
在“非数值”概念的大多数实现中,NaN 不被视为与任何其他数值相等(包括 NaN)。为了使数值能够排序并用于树形索引,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 位。值过大或过小都会报错;输入精度过高时可能发生舍入。过于接近零、无法表示为区别于零的数值时,会报下溢错误。
默认情况下,浮点值以最短的精确十进制表示形式输出为文本;生成的十进制值与实际存储的二进制值之间的距离,小于它与相同二进制精度下任何其他可表示值之间的距离。(不过,目前输出值绝不会恰好位于两个可表示值的正中间,以避开输入例程未正确遵守舍入到最近偶数规则这一常见缺陷。)对于 float8 值,这种表示最多使用 17 位十进制有效数字;对于 float4 值,最多使用 9 位。
注意
这种最短精确输出格式的生成速度,远高于历史上使用的舍入格式。
为兼容旧版 PostgreSQL 生成的输出,并允许降低输出精度,可以使用 extra_float_digits 参数改为选择舍入后的十进制输出。设置为 0 会恢复此前的默认行为,将值舍入为 6 位(float4)或 15 位(float8)十进制有效数字。负值会进一步减少位数;例如,-2 会分别将输出舍入为 4 位或 13 位。
任何大于 0 的 extra_float_digits 值都会选择最短精确格式。
注意
过去,需要精确值的应用必须将 extra_float_digits 设为 3 才能获得这些值。为了最大限度地兼容不同版本,它们应继续这样设置。
除普通数值外,浮点类型还有几个特殊值:
Infinity
-Infinity
NaN
这些值分别表示 IEEE 754 特殊值“正无穷”“负无穷”和“非数”。在 SQL 命令中将它们写成常量时,必须加引号,例如 UPDATE table SET x = '-Infinity'。输入识别时不区分大小写,无穷值也可写为 inf 和 -inf。
注意
IEEE 754 规定,NaN 不应与任何其他浮点值相等(包括 NaN)。为了使浮点值能够排序并用于树形索引,PostgreSQL 将 NaN 值视为彼此相等,且大于所有非 NaN 值。
PostgreSQL 也支持 SQL 标准的 float 和 float(p) 记法来指定非精确数值类型。p 表示可接受的最小二进制位精度。float(1) 到 float(24) 选择 real 类型,float(25) 到 float(53) 选择 double precision。p 超出允许范围会报错;不指定精度的 float 等同于 double precision。
8.1.4. 序列类型
注意
本节介绍 PostgreSQL 特有的自动递增列创建方法。另一种方法是使用 SQL 标准的标识列特性,参见第 5.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;
这样就创建了一个 integer 列,并安排由序列生成器提供默认值。NOT NULL 约束保证无法插入空值。(多数情况下还应增加 UNIQUE 或 PRIMARY KEY 约束,防止意外插入重复值,但系统不会自动添加。)最后,序列被标记为归该列所有,因此删除列或表时,序列也会被删除。
注意
由于 smallserial、serial 和 bigserial 使用序列实现,即使从未删除任何行,列中出现的值序列也可能存在“空洞”或间隙。即便包含所分配值的行从未成功插入表列,从序列分配的值仍已被“用掉”。例如,插入事务回滚时就会发生这种情况。详见第 9.17 节的 nextval()。
要将序列的下一个值插入 serial 列,应让该列使用默认值。可以在 INSERT 的列列表中省略此列,也可以使用 DEFAULT 关键字。
serial 与 serial4 等价,都会创建 integer 列。bigserial 与 serial8 的工作方式相同,只是创建 bigint 列。如果预计表的整个生命周期内使用的标识符超过 2^31 个,应使用 bigserial。smallserial 与 serial2 也采用相同方式,但创建 smallint 列。
为 serial 列创建的序列会在所属列被删除时自动删除。也可以只删除序列而保留列,但这会强制移除列的默认值表达式。
版本比较
PostgreSQL 17.11 → 18.6。属性比较不包含构建标识和说明正文;原始目录字段与源描述保留原文。
这两个样本的系统目录和结构化属性没有变化。
这些构建的文档也有差异,请查看对应版本的手册定义。
文档与源码
- 构建
- 18.6 · https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2
- 指纹
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f
全部数据类型 · 下载此版本 JSON · 最早收录的样本不代表该类型的实际引入版本。