↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / 数据类型 / 数值

smallint

有符号两字节整数

当前查看 PostgreSQL 18.6。

PG10–20 核心源码清单。类型转换与操作符类列出源码显式声明的关系;缺少记录不能排除通过其他机制进行转换或使用索引。

定义

SQL 名称与别名: int2

有符号两字节整数

smallint
目录名称
pg_catalog.int2
类型 OID
21
类型种类
基础类型
声明长度
2 字节
存储策略
plain
输入函数
int2in
输出函数
int2out
手册中的声明
smallint
存储大小
2 字节
手册说明
小范围整数
范围
-32768 到 +32767

中文手册

阅读完整手册章节

阅读来源定义

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 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;

这样就创建了一个 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 列创建的序列会在所属列被删除时自动删除。也可以只删除序列而保留列,但这会强制移除列的默认值表达式。

系统目录属性

此构建的源码初始化值。字段含义参见 pg_type 。包含头文件默认值;依赖构建的常量保留符号形式,不作为服务器运行时实测。

oid
21
descr
-32 thousand to 32 thousand, 2-byte storage
typacl
_null_
typlen
2
typelem
0
typname
int2
typsend
int2send
typtype
b
typalign
s
typarray
0
typbyval
t
typdelim
','
typinput
int2in
typmodin
-
typndims
0
typowner
POSTGRES
typrelid
0
typmodout
-
typoutput
int2out
typtypmod
-1
typanalyze
-
typdefault
_null_
typnotnull
f
typreceive
int2recv
typstorage
p
typbasetype
0
typcategory
N
typcollation
0
typisdefined
t
typnamespace
pg_catalog
typsubscript
-
typdefaultbin
_null_
array_type_oid
1005
typispreferred
f
array_type_name
_int2

类型转换 25

与此类型相关的显式 pg_cast 记录。PostgreSQL 还支持 pg_cast 之外的类型转换,缺少记录不能证明转换不可能。

源类型目标类型转换上下文转换方式函数
int8int2赋值函数int2(int8)
int2int8隐式函数int8(int2)
int2int4隐式函数int4(int2)
int2float4隐式函数float4(int2)
int2float8隐式函数float8(int2)
int2numeric隐式函数numeric(int2)
int4int2赋值函数int2(int4)
float4int2赋值函数int2(float4)
float8int2赋值函数int2(float8)
numericint2赋值函数int2(numeric)
int2oid隐式函数int4(int2)
int2regproc隐式函数int4(int2)
int2regprocedure隐式函数int4(int2)
int2regoper隐式函数int4(int2)
int2regoperator隐式函数int4(int2)
int2regclass隐式函数int4(int2)
int2regcollation隐式函数int4(int2)
int2regtype隐式函数int4(int2)
int2regconfig隐式函数int4(int2)
int2regdictionary隐式函数int4(int2)
int2regrole隐式函数int4(int2)
int2regnamespace隐式函数int4(int2)
int2bytea显式函数bytea(int2)
byteaint2显式函数int2(bytea)
jsonbint2显式函数int2(jsonb)

运算符重载 63

每种操作数签名均为独立重载。实现函数和返回类型来自同一源码构建。

运算符左操作数右操作数返回类型含义实现函数
=int2int2bool等于int2eq
<int2int2bool小于int2lt
<>int2int2bool不等于int2ne
>int2int2bool大于int2gt
<=int2int2bool小于等于int2le
>=int2int2bool大于等于int2ge
*int2int2int2相乘int2mul
/int2int2int2相除int2div
%int2int2int2取模int2mod
=int2int4bool等于int24eq
=int4int2bool等于int42eq
<int2int4bool小于int24lt
<int4int2bool小于int42lt
>int2int4bool大于int24gt
>int4int2bool大于int42gt
<>int2int4bool不等于int24ne
<>int4int2bool不等于int42ne
<=int2int4bool小于等于int24le
<=int4int2bool小于等于int42le
>=int2int4bool大于等于int24ge
>=int4int2bool大于等于int42ge
*int2int4int4相乘int24mul
*int4int2int4相乘int42mul
/int2int4int4相除int24div
/int4int2int4相除int42div
+int2int2int2相加int2pl
+int2int4int4相加int24pl
+int4int2int4相加int42pl
-int2int2int2相减int2mi
-int2int4int4相减int24mi
-int4int2int4相减int42mi
-无(一元)int2int2取相反数int2um
@无(一元)int2int2绝对值int2abs
+int8int2int8相加int82pl
-int8int2int8相减int82mi
*int8int2int8相乘int82mul
/int8int2int8相除int82div
+int2int8int8相加int28pl
-int2int8int8相减int28mi
*int2int8int8相乘int28mul
/int2int8int8相除int28div
*moneyint2money相乘cash_mul_int2
/moneyint2money相除cash_div_int2
*int2moneymoney相乘int2_mul_cash
=int2int8bool等于int28eq
<>int2int8bool不等于int28ne
<int2int8bool小于int28lt
>int2int8bool大于int28gt
<=int2int8bool小于等于int28le
>=int2int8bool大于等于int28ge
=int8int2bool等于int82eq
<>int8int2bool不等于int82ne
<int8int2bool小于int82lt
>int8int2bool大于int82gt
<=int8int2bool小于等于int82le
>=int8int2bool大于等于int82ge
&int2int2int2按位与int2and
|int2int2int2按位或int2or
#int2int2int2按位异或int2xor
~无(一元)int2int2按位取反int2not
<<int2int4int2按位左移int2shl
>>int2int4int2按位右移int2shr
+无(一元)int2int2一元正号int2up

操作符类 5

声明输入类型与此类型相符的操作符类。多态操作符类、类型转换和表达式索引还可能提供其他索引路径;不能仅凭此表判断是否支持索引。

操作符类索引方法输入类型操作符族默认存储类型
int2_opsbtreeint2btree/integer_ops是与输入类型相同
int2_opshashint2hash/integer_ops是与输入类型相同
int2_minmax_opsbrinint2brin/integer_minmax_ops是int2
int2_minmax_multi_opsbrinint2brin/integer_minmax_multi_ops否int2
int2_bloom_opsbrinint2brin/integer_bloom_ops否int2

版本比较

PostgreSQL 17.11 → 18.6。属性比较不包含构建标识和说明正文;原始目录字段与源描述保留原文。

类型转换

PostgreSQL 17.11

[{"castcontext": "a", "castfunc": "int2(float4)", "castmethod": "f", "castsource": "float4", "casttarget": "int2"}, {"castcontext": "a", "castfunc": "int2(float8)", "castmethod": "f", "castsource": "float8", "casttarget": "int2"}, {"castcontext": "a", "castfunc": "int2(int4)", "castmethod": "f", "castsource": "int4", "casttarget": "int2"}, {"castcontext": "a", "castfunc": "int2(int8)", "castmethod": "f", "castsource": "int8", "casttarget": "int2"}, {"castcontext": "a", "castfunc": "int2(numeric)", "castmethod": "f", "castsource": "numeric", "casttarget": "int2"}, {"castcontext": "e", "castfunc": "int2(jsonb)", "castmethod": "f", "castsource": "jsonb", "casttarget": "int2"}, {"castcontext": "i", "castfunc": "float4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "float4"}, {"castcontext": "i", "castfunc": "float8(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "float8"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "int4"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "oid"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regclass"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regcollation"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regconfig"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regdictionary"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regnamespace"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regoper"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regoperator"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regproc"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regprocedure"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regrole"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regtype"}, {"castcontext": "i", "castfunc": "int8(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "int8"}, {"castcontext": "i", "castfunc": "numeric(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "numeric"}]

PostgreSQL 18.6

[{"castcontext": "a", "castfunc": "int2(float4)", "castmethod": "f", "castsource": "float4", "casttarget": "int2"}, {"castcontext": "a", "castfunc": "int2(float8)", "castmethod": "f", "castsource": "float8", "casttarget": "int2"}, {"castcontext": "a", "castfunc": "int2(int4)", "castmethod": "f", "castsource": "int4", "casttarget": "int2"}, {"castcontext": "a", "castfunc": "int2(int8)", "castmethod": "f", "castsource": "int8", "casttarget": "int2"}, {"castcontext": "a", "castfunc": "int2(numeric)", "castmethod": "f", "castsource": "numeric", "casttarget": "int2"}, {"castcontext": "e", "castfunc": "bytea(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "bytea"}, {"castcontext": "e", "castfunc": "int2(bytea)", "castmethod": "f", "castsource": "bytea", "casttarget": "int2"}, {"castcontext": "e", "castfunc": "int2(jsonb)", "castmethod": "f", "castsource": "jsonb", "casttarget": "int2"}, {"castcontext": "i", "castfunc": "float4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "float4"}, {"castcontext": "i", "castfunc": "float8(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "float8"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "int4"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "oid"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regclass"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regcollation"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regconfig"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regdictionary"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regnamespace"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regoper"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regoperator"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regproc"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regprocedure"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regrole"}, {"castcontext": "i", "castfunc": "int4(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "regtype"}, {"castcontext": "i", "castfunc": "int8(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "int8"}, {"castcontext": "i", "castfunc": "numeric(int2)", "castmethod": "f", "castsource": "int2", "casttarget": "numeric"}]

这些构建的文档也有差异,请查看对应版本的手册定义。

文档与源码

构建
18.6 · https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2
指纹
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f

相关条目

全部数据类型 · 下载此版本 JSON · 最早收录的样本不代表该类型的实际引入版本。