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

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 7.4 已于 2010 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

第 8 章 数据类型

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

表 8.1 列出了所有内建的通用数据类型。“别名”列中列出的大多数替代名称,是 PostgreSQL 出于历史原因在内部使用的名称。此外还有一些内部使用或已废弃的类型可用,但这里没有列出。

表 8.1. 数据类型

名字 别名 描述
bigint int8 有符号的8字节整数
bigserial serial8 自动递增的8字节整数
bit   定长位串
bit varying(n) varbit(n) 变长位串
boolean bool 逻辑布尔值(真/假)
box   平面上的矩形框
bytea   二进制数据
character varying(n) varchar(n) 变长字符串
character(n) char(n) 定长字符串
cidr   IPv4或IPv6网络地址
circle   平面上的圆
date   日历日期(年、月、日)
double precision float8 双精度浮点数
inet   IPv4或IPv6主机地址
integer int, int4 有符号4字节整数
interval(p)   时间段
line   平面上的无限直线(未完全实现)
lseg   平面上的线段
macaddr   MAC 地址
money   货币数量
numeric [ (p, s) ] decimal [ (p, s) ] 精度可选择的精确数值
path   平面上的开放和闭合几何路径
point   平面上的几何点
polygon   平面上的封闭几何路径
real float4 单精度浮点数
smallint int2 有符号2字节整数
serial serial4 自动递增的4字节整数
text   变长字符串
time [ (p) ] [ without time zone ]   一天中的时间
time [ (p) ] with time zone timetz 一天中的时间,包括时区
timestamp [ (p) ] [ without time zone ] timestamp 日期和时间
timestamp [ (p) ] with time zone timestamptz 日期和时间,包括时区

兼容性

下列类型(或它们的这些拼写形式)由SQL规定:bit、bit varying、boolean、char、character varying、character、varchar、date、double precision、integer、interval、numeric、decimal、real、smallint、time(有时区或无时区)、timestamp(有时区或无时区)。

每种数据类型都有由其输入和输出函数决定的外部表示。许多内建类型都有显而易见的外部格式。但也有一些类型要么为 PostgreSQL 所独有(例如开放和闭合路径),要么有多种可选格式(例如日期和时间类型)。 有些输入和输出函数是不可逆的。也就是说,输出函数的结果与原始输入相比可能损失精度。

为了提高执行速度,某些运算符和函数(例如加法和乘法)不做运行时错误检查。例如在某些系统上,某些数据类型的数值运算符可能静默地导致下溢或上溢。

8.1. 数字类型 #

数值类型包括二字节、四字节和八字节整数,四字节和八字节浮点数,以及固定精度的小数。表 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数据库系统中使用。

注意

如果你有一个带索引的 smallint 或 bigint 类型的列,可能会遇到系统不使用该索引的问题。例如,如下形式的子句

... WHERE smallint_column = 42

不会使用索引,因为系统把类型 integer 指派给常量 42,而 PostgreSQL 目前在涉及两种不同数据类型时无法使用索引。一个变通办法是给常量加单引号,即:

... WHERE smallint_column = '42'

这会使系统推迟类型解析,从而为常量指派正确的类型。

8.1.2. 任意精度数字 #

numeric 类型最多可存储 1000 位精度的数字并精确执行计算。特别推荐用它存储货币金额和其他要求精确的数量。但与下一节描述的浮点类型相比,numeric 类型非常慢。

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

numeric 类型的精度和小数位数都可以配置。要声明一个 numeric 类型的列,可使用如下语法

NUMERIC(precision, scale)

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

NUMERIC(precision)

选择小数位数 0。指定

NUMERIC

而不带任何精度和小数位数,则会创建一个可以存储任意精度和小数位数的数值的列,精度上限为实现限制。这种列不会把输入值强制转换为任何特定的小数位数,而声明了小数位数的 numeric 列会把输入值强制转换为该小数位数。(SQL 标准要求默认小数位数为 0,即强制转换为整数精度。我们觉得这没什么用处。如果你关心可移植性,就总是显式指定精度和小数位数。)

如果一个值的精度或小数位数大于列所声明的精度或小数位数,系统会尝试对该值四舍五入。如果无法通过四舍五入满足声明的限制,则会引发一个错误。

类型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 位数字。过大或过小的值会导致错误。如果输入数字的精度过高,可能会发生舍入。过于接近零且无法表示为与零不同的数值,会导致下溢错误。

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 DEFAULT nextval('tablename_colname_seq') NOT NULL
);

这样,我们就创建了一个整型列,并安排它的默认值由一个序列产生器分配。这里应用了NOT NULL约束,以确保不会插入空值。在大多数情况下,你可能还会想附加一个UNIQUE或PRIMARY KEY约束,以防止意外插入重复值,但这不是自动的。

注意

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

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

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

为 serial 列创建的序列会在所属列被删除时自动删除,且不能以其他方式删除。(在 PostgreSQL 7.3 之前的版本中并非如此。注意,对于通过重新加载 7.3 之前数据库的转储创建的序列,这种自动删除链接不会发生;转储文件不含建立依赖链接所需的信息。)此外,序列与列之间的这种依赖只针对 serial 列本身建立;如果有其他列引用该序列(例如通过手动调用 nextval 函数),在序列被删除时它们将被破坏。以这种方式使用 serial 列的序列被认为是不好的做法;如果你想让多个列共用同一个序列生成器,请把序列创建为独立对象。

提交更正

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