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

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

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 8.4 已于 2014 年 7 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

第 8 章 数据类型

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

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

表 8.1. 数据类型

名字 别名 描述
bigint int8 有符号的8字节整数
bigserial serial8 自动递增的8字节整数
bit [ (n) ]   定长位串
bit varying [ (n) ] varbit 变长位串
boolean bool 逻辑布尔值(真/假)
box   平面上的矩形框
bytea   二进制数据(“字节数组”)
character varying [ (n) ] varchar [ (n) ] 变长字符串
character [ (n) ] char [ (n) ] 定长字符串
cidr   IPv4或IPv6网络地址
circle   平面上的圆
date   日历日期(年、月、日)
double precision float8 双精度浮点数(8 字节)
inet   IPv4或IPv6主机地址
integer int, int4 有符号4字节整数
interval [ fields ] [ (p) ]   时间段
line   平面上的无限长的线
lseg   平面上的线段
macaddr   MAC(Media Access Control)地址
money   货币数量
numeric [ (p, s) ] decimal [ (p, s) ] 可选择精度的精确数字
path   平面上的几何路径
point   平面上的几何点
polygon   平面上的封闭几何路径
real float4 单精度浮点数(4字节)
smallint int2 有符号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规定:bigint、bit、bit varying、boolean、char、character varying、character、varchar、date、double precision、integer、interval、numeric、decimal、real、smallint、time(有时区或无时区)、timestamp(有时区或无时区)、xml。

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

8.1. 数字类型 #

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

表 8.2. 数字类型

名字 存储尺寸 描述 范围
smallint 2字节 小范围整数 -32768 到 +32767
integer 4字节 整数的典型选择 -2147483648 到 +2147483647
bigint 8字节 大范围整数 -9223372036854775808 到 9223372036854775807
decimal 可变 用户指定精度,精确 无限制
numeric 可变 用户指定精度,精确 无限制
real 4字节 可变精度,不精确 6位十进制精度
double precision 8字节 可变精度,不精确 15位十进制精度
serial 4字节 自动递增的整数 1到2147483647
bigserial 8字节 自动递增的大整数 1到9223372036854775807

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

8.1.1. 整数类型 #

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

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

在非常精简的操作系统上,bigint类型可能无法正确工作,因为它依赖于编译器对八字节整数的支持。在这样的机器上,bigint的行为与integer相同,但仍占用八个字节的存储空间。(我们不知道有任何现代平台属于这种情况。)

SQL只规定了整数类型integer(或int)、smallint和bigint。类型int2、int4和int8都是扩展,也在某些其他SQL数据库系统中使用。

8.1.2. 任意精度数值 #

类型numeric可以存储最多 1000 位精度的数字并精确地执行计算。我们特别建议将它用于货币金额和其他要求精确的数量。不过,numeric类型上的算术运算比整数类型或者下一节描述的浮点数类型要慢很多。

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

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

NUMERIC(precision, scale)

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

NUMERIC(precision)

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

NUMERIC

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

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

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

除了普通数值外,numeric类型还允许特殊值NaN,表示“非数”。对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 位数字。过大或过小的值会导致错误。如果输入数字的精度过高,可能会发生舍入。过于接近零且无法表示为与零不同的数值,会导致下溢错误。

注意

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

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

Infinity
-Infinity
NaN

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

注意

IEEE 754 规定,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。

注意

在PostgreSQL 7.4 之前,float(p)中的精度被理解为这么多位十进制数字。现在这一点已被纠正,以符合 SQL 标准,即精度以二进制位来衡量。假定real和double precision的尾数分别恰好有 24 位和 53 位,对于 IEEE 标准浮点实现而言是正确的。在非 IEEE 平台上可能会有少许偏差,但为简单起见,所有平台都使用相同的p取值范围。

8.1.4. serial 类型 #

serial和bigserial并不是真正的数据类型,它们只是为了创建唯一标识符列而提供的记法便利(类似于其他一些数据库支持的AUTO_INCREMENT属性)。在当前实现中,下列语句:

CREATE TABLE tablename (
    colname SERIAL
);

等价于以下语句:

CREATE SEQUENCE tablename_colname_seq;
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约束,以防止意外插入重复值,但这不是自动的。)最后,该序列被标记为由该列“拥有”,因此当列或表被删除时,它也会被删除。

注意

在PostgreSQL 7.3 之前,serial隐含UNIQUE。现在这不再是自动的。如果希望一个 serial 列具有唯一约束或作为主键,现在必须像对待任何其他数据类型一样显式指定。

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

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

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

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。