选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

Chapter 8. 数据类型

目录

8.1. 数字类型
8.1.1. 整数类型
8.1.2. 任意精度数值
8.1.3. 浮点类型
8.1.4. serial 类型
8.2. 货币类型
8.3. 字符类型
8.4. 二进制数据类型
8.4.1. bytea的十六进制格式
8.4.2. bytea的转义格式
8.5. 日期/时间类型
8.5.1. 日期/时间输入
8.5.2. 日期/时间输出
8.5.3. 时区
8.5.4. 间隔输入
8.5.5. 间隔输出
8.6. 布尔类型
8.7. 枚举类型
8.7.1. 枚举类型的声明
8.7.2. 排序
8.7.3. 类型安全性
8.7.4. 实现细节
8.8. 几何类型
8.8.1. 点
8.8.2. 线
8.8.3. 线段
8.8.4. 方框
8.8.5. 路径
8.8.6. 多边形
8.8.7. 圆
8.9. 网络地址类型
8.9.1. inet
8.9.2. cidr
8.9.3. inet vs. cidr
8.9.4. macaddr
8.9.5. macaddr8
8.10. 位串类型
8.11. 文本搜索类型
8.11.1. tsvector
8.11.2. tsquery
8.12. UUID类型
8.13. XML类型
8.13.1. 创建XML值
8.13.2. 编码处理
8.13.3. 访问XML值
8.14. JSON 类型
8.14.1. JSON 输入和输出语法
8.14.2. 有效地设计 JSON 文档
8.14.3. jsonb 包含与存在
8.14.4. jsonb 索引
8.14.5. 转换
8.15. 数组
8.15.1. 数组类型的声明
8.15.2. 数组值输入
8.15.3. 访问数组
8.15.4. 修改数组
8.15.5. 在数组中搜索
8.15.6. 数组输入和输出语法
8.16. 复合类型
8.16.1. 复合类型的声明
8.16.2. 构造组合值
8.16.3. 访问复合类型
8.16.4. 修改组合值
8.16.5. 在查询中使用复合类型
8.16.6. 复合类型的输入和输出语法
8.17. 范围类型
8.17.1. 内置范围类型
8.17.2. 示例
8.17.3. 包含界限与排除界限
8.17.4. 无限(无界)范围
8.17.5. 范围输入/输出
8.17.6. 构造范围
8.17.7. 离散范围类型
8.17.8. 定义新的范围类型
8.17.9. 索引
8.17.10. 范围上的约束
8.18. 域类型
8.19. 对象标识符类型
8.20. pg_lsn 类型
8.21. 伪类型

PostgreSQL 提供了丰富的原生数据类型。 用户可以使用CREATE TYPE命令向 PostgreSQL添加新类型。

Table 8.1展示了所有内置的通用数据类型。 别名列中列出的多数可选名称,都是 PostgreSQL出于历史原因在内部使用的名称。 此外,还有一些内部使用或已废弃的类型也可用,但未在此列出。

Table 8.1. 数据类型

名字 别名 描述
bigint int8 有符号的8字节整数
bigserial serial8 自动递增的8字节整数
bit [ (n) ]   定长位串
bit varying [ (n) ] varbit [ (n) ] 变长位串
boolean bool 逻辑布尔值(真/假)
box   平面上的矩形框
bytea   二进制数据(字节数组
character [ (n) ] char [ (n) ] 定长字符串
character varying [ (n) ] varchar [ (n) ] 变长字符串
cidr   IPv4或IPv6网络地址
circle   平面上的圆
date   日历日期(年、月、日)
double precision float8 双精度浮点数(8 字节)
inet   IPv4或IPv6主机地址
integer int, int4 有符号4字节整数
interval [ fields ] [ (p) ]   时间段
json   文本 JSON 数据
jsonb   二进制 JSON 数据,已分解
line   平面上的无限长的线
lseg   平面上的线段
macaddr   MAC(Media Access Control)地址
macaddr8   MAC(Media Access Control)地址(EUI-64格式)
money   货币数量
numeric [ (p, s) ] decimal [ (p, s) ] 可选择精度的精确数字
path   平面上的几何路径
pg_lsn   PostgreSQL日志序列号类型
point   平面上的几何点
polygon   平面上的封闭几何路径
real float4 单精度浮点数(4字节)
smallint int2 有符号2字节整数
smallserial serial2 自动递增的2字节整数
serial serial4 自动递增的4字节整数
text   变长字符串
time [ (p) ] [ without time zone ]   一天中的时间(无时区)
time [ (p) ] with time zone timetz 一天中的时间,包括时区
timestamp [ (p) ] [ without time zone ]   日期和时间(无时区)
timestamp [ (p) ] with time zone timestamptz 日期和时间,包括时区
tsquery   文本搜索查询
tsvector   文本搜索文档
txid_snapshot   用户级事务 ID 快照
uuid   通用唯一标识符
xml   XML 数据

兼容性

下列类型(或它们的这些拼写形式)由SQL规定:bigintbitbit varyingbooleancharcharacter varyingcharactervarchardatedouble precisionintegerintervalnumericdecimalrealsmallinttime(有时区或无时区)、timestamp(有时区或无时区)、xml

每种数据类型都有一种由其输入和输出函数决定的外部表示。 许多内置类型的外部格式都很直观。不过,也有一些类型是 PostgreSQL所特有的,例如几何路径; 还有一些类型可能存在多种可能的格式,例如日期/时间类型。 有些输入和输出函数并不可逆,也就是说,输出函数的结果与原始 输入相比可能会丢失精度。

8.1. 数字类型 #

数字类型包括 2、4、8 字节的整数,4、8 字节的浮点数, 以及可选精度的小数。Table 8.2 列出了所有可用类型。

Table 8.2. 数字类型

名字 存储尺寸 描述 范围
smallint 2字节 小范围整数 -32768 to +32767
integer 4字节 整数的典型选择 -2147483648 to +2147483647
bigint 8字节 大范围整数 -9223372036854775808 to +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

数字类型常量的语法在Section 4.1.2里描述。数字类型有一整套对应的数学操作符和函数。相关信息请参考 Chapter 9。下面的几节详细描述这些类型。

8.1.1. 整数类型 #

类型 smallintintegerbigint 用于存储不同范围的整数,也就是没有小数部分的数。 试图存储超出允许范围的值会导致错误。

常用的类型是integer,因为它提供了在范围、存储空间和性能之间的最佳平衡。一般只有在磁盘空间紧张的时候才使用 smallint类型。而只有在integer的范围不够的时候才使用bigint

SQL只声明了整数类型integer(或int)、smallintbigint。类型int2int4int8都是扩展,也在许多其它SQL数据库系统中使用。

8.1.2. 任意精度数值 #

类型numeric可以存储非常多位的数字。我们特别建议将它用于货币金额和其它要求计算准确的数量。numeric值的计算在可能的情况下会得到准确的结果,例如加法、减法、乘法。不过,numeric类型上的算术运算比整数类型或者下一节描述的浮点数类型要慢很多。

下面使用如下术语:numeric精度是整个数中有效数字的总数,即小数点两侧的数字位数之和。numeric小数位数是小数部分中十进制数字的数量,即小数点右侧的位数。因此,数值 23.5141 的精度为 6,小数位数为 4。整数可以视为小数位数为零。

可以配置numeric列的最大精度和最大小数位数。要声明numeric类型的列,使用以下语法:

NUMERIC(precision, scale)

精度必须为正数,小数位数必须为零或正数。也可以使用:

NUMERIC(precision)

这会选择小数位数为 0。指定:

NUMERIC

而不指定任何精度或小数位数,会创建一个可存储任意精度和小数位数数值的列,直到达到实现对精度的限制。这种列不会把输入值强制转换为某个特定的小数位数,而声明了小数位数的numeric列会将输入值强制转换为该小数位数。(SQL标准要求默认小数位数为 0,即强制转换为整数精度。我们认为这没有多少用处。如果你关心可移植性,请始终显式指定精度和小数位数。)

Note

在类型声明中显式指定精度时,所允许的最大值为 1000;未指定精度的NUMERICTable 8.2中所述限制的约束。

如果要存储的值的小数位数大于该列声明的小数位数,系统会把该值 舍入到指定的小数位数。然后,如果小数点左侧的位数超过了声明的 精度减去声明的小数位数,就会报错。

数值在物理上存储时不会保留多余的前导零或尾随零。因此,列上 声明的精度和小数位数只是最大值,而不是固定分配的空间 (从这个意义上说,numeric更像 varchar(n),而不像 char(n))。实际存储需求 是每四个十进制数字组占两个字节,再加上 3 到 8 字节的开销。

除了普通数值外,numeric类型还允许特殊值NaN,表示非数。对NaN的任何运算都会产生另一个NaN。在 SQL 命令中将该值写为常量时,必须加上引号,例如UPDATE table SET x = 'NaN'。输入时,字符串NaN的识别不区分大小写。

Note

在大多数非数字概念的实现中,NaN 都被认为不等于任何其他数值(包括 NaN 本身)。 为了让 numeric 值能够排序并用于基于树的索引, PostgreSQLNaN 值视为彼此相等,并且大于所有非 NaN 值。

类型decimalnumeric是等效的。两种类型都是SQL标准的一部分。

进行舍入时,numeric类型在遇到恰好处于中间的值时, 会朝远离零的方向舍入;而(在大多数机器上) realdouble 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. 浮点类型 #

数据类型realdouble precision是不精确的、变精度的数字类型。实际上,在底层处理器、操作系统和编译器支持的范围内,这两种类型通常实现了IEEE 754 二进制浮点算术标准(分别对应单精度和双精度)。

所谓不精确,是指某些值无法被精确转换为内部格式,只能以近似值 存储,因此存储并再取出一个值时,可能会看到轻微差异。如何处理 这类误差以及它们在计算中如何传播,是数学和计算机科学中的一个 独立领域,这里不再展开,只强调以下几点:

  • 如果你要求准确的存储和计算(例如计算货币金额),应使用numeric类型。

  • 如果你想用这些类型进行任何重要的复杂计算,尤其是依赖边界情形 (无穷大、下溢)特定行为的计算,那么应该仔细评估其实现。

  • 比较两个浮点值是否相等,未必总能得到符合预期的结果。

在大多数平台上,real类型的范围至少为 1E-37 到 1E+37,精度至少为 6 位十进制数字。double precision类型的范围通常约为 1E-307 到 1E+308,精度至少为 15 位数字。过大或过小的值会导致错误。如果输入数字的精度过高,可能会发生舍入。过于接近零且无法表示为与零不同的数值,会导致下溢错误。

Note

extra_float_digits设置控制浮点值转换为文本输出时所包含的额外有效数字位数。使用默认值0时,输出在 PostgreSQL 支持的每个平台上都相同。增大该值会使输出更精确地表示所存储的值,但可能不具有可移植性。

除了普通数值外,浮点类型还有几个特殊值:


Infinity
-Infinity
NaN

它们分别表示 IEEE 754 的特殊值无穷大负无穷大非数字。(在浮点运算不遵循 IEEE 754 的机器上,这些值可能无法按预期工作。)在 SQL 命令中将这些值写为常量时,必须加上引号,例如UPDATE table SET x = '-Infinity'。输入时,这些字符串的识别不区分大小写。

Note

IEEE 754 规定,NaN 不应与任何其他浮点值 (包括NaN)相等。为了允许浮点值被排序, 并可用于基于树的索引,PostgreSQLNaN视为彼此相等,并且大于所有非 NaN值。

PostgreSQL 也支持 SQL 标准记法 floatfloat(p) 来指定不精确数值 类型。这里,p 指定可接受的最小 二进制精度位数。 PostgreSQLfloat(1)float(24) 视为选择 real 类型,而 float(25)float(53) 则选择 double precisionp 超出允许范围会报错。未指定精度的 float 视为 double precision

Note

假定realdouble precision的尾数分别恰好有 24 位和 53 位,对于 IEEE 标准浮点实现而言是正确的。在非 IEEE 平台上可能会有少许偏差,但为简单起见,所有平台都使用相同的p取值范围。

8.1.4. serial 类型 #

Note

本节描述的是 PostgreSQL 特有的创建自动递增列的方法。另一种方法是使用 SQL 标准的标识列特性,参见CREATE TABLE

smallserialserialbigserial 并不是真正的数据类型,它们只是为了创建 唯一标识符列而提供的记法便利(类似于其他一些数据库支持的 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约束,以确保不能插入空值。 (在大多数情况下,你可能还会希望再加上UNIQUEPRIMARY KEY约束,以防意外插入重复值,但这 不会自动发生。)最后,该序列会被标记为属于该列, 这样当列或表被删除时,序列也会随之删除。

Note

因为 smallserialserialbigserial 是用序列实现的,所以即使没有删除任何 行,列中出现的值序列也可能存在空洞或缺口。 即使包含该值的行从未成功插入表中,从序列分配出去的值仍会被 视为已使用。例如,如果插入事务回滚,就会 发生这种情况。详细信息见 Section 9.16 中的 nextval()

要向 serial 列插入序列中的下一个值,应指定让serial列 使用其默认值。这既可以通过在 INSERT 语句的 列表中省略该列来实现,也可以通过使用 DEFAULT 关键字来实现。

类型名 serialserial4 是等价的: 二者都会创建 integer 列。类型名 bigserialserial8 的工作方式相同, 只是它们创建的是 bigint 列。如果预计表在其生命 周期内会使用超过 231 个标识符, 就应使用 bigserial。类型名 smallserialserial2 也同理, 只是它们创建的是 smallint 列。

serial 列创建的序列会在其所属列被删除时自动删除。 你也可以在不删除该列的情况下删除该序列,但这会强制移除该列的默认值 表达式。