↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 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.3 已结束支持。 请参阅 当前版本手册.

第 5 章 数据类型

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

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

表 5.1. 数据类型

类型名别名描述
bigintint8有符号的8字节整数
bigserialserial8自动递增的8字节整数
bit 定长位串
bit varying(n)varbit(n)变长位串
booleanbool逻辑布尔值(真/假)
box 二维平面上的矩形框
bytea 二进制数据
character varying(n)varchar(n)变长字符串
character(n)char(n)定长字符串
cidr IP 网络地址
circle 二维平面上的圆
date 日历日期(年、月、日)
double precisionfloat8双精度浮点数
inet IP 主机地址
integerint, int4有符号4字节整数
interval(p) 通用时间段
line 二维平面上的无限直线(未实现)
lseg 二维平面上的线段
macaddr MAC 地址
money 货币数量
numeric [ (p, s) ]decimal [ (p, s) ]精度可选择的精确数值
path 二维平面上的开放和闭合几何路径
point 二维平面上的几何点
polygon 二维平面上的封闭几何路径
realfloat4单精度浮点数
smallintint2有符号2字节整数
serialserial4自动递增的4字节整数
text 变长字符串
time [ (p) ] [ without time zone ] 一天中的时间
time [ (p) ] with time zonetimetz一天中的时间,包括时区
timestamp [ (p) ] without time zonetimestamp日期和时间
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 所独有(例如开放和闭合路径),要么有多种可选格式(例如日期和时间类型)。大多数对应于基本类型(如整数和浮点数)的输入和输出函数会做一些错误检查。有些输入和输出函数是不可逆的。也就是说,输出函数的结果与原始输入相比可能损失精度。

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

5.1. 数字类型 #

数值类型包括二字节、四字节和八字节整数,四字节和八字节浮点数,以及固定精度的小数。表 5.2列出了可用的类型。

表 5.2. 数字类型

类型名Storage size描述范围
smallint2字节小范围定点数-32768 到 +32767
integer4字节定点数的常用选择-2147483648 到 +2147483647
bigint8字节大范围定点数-9223372036854775808 到 9223372036854775807
decimal可变用户指定精度,精确无限制
numeric可变用户指定精度,精确无限制
real4字节可变精度,不精确6位十进制精度
double precision8字节可变精度,不精确15位十进制精度
serial4字节自动递增的整数1到2147483647
bigserial8字节自动递增的大整数1到9223372036854775807

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

5.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'

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

5.1.2. 任意精度数字 #

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

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

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

NUMERIC(precision, scale)

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

NUMERIC(precision)

选择小数位数 0。指定

NUMERIC

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

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

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

5.1.3. 浮点类型 #

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

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

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

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

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

通常,real 类型的取值范围至少是 -1E+37 到 +1E+37,精度至少为 6 位十进制数字。double precision 类型通常的取值范围约为 -1E+308 到 +1E+308,精度至少 15 位。太大或太小的值会导致错误。输入数字精度过高时可能发生四舍五入。与零太接近而无法与零区分的数字会导致下溢错误。

5.1.4. serial 类型 #

serial 数据类型并不是真正的类型,而只是设置标识符列的一种记法上的便利(类似于某些其他数据库支持的 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约束,以防止意外插入重复值,但这不是自动的。

要使用 serial 列把序列的下一个值插入表中,需指定让该 serial 列取默认值。这可以通过在 INSERT 语句的列清单中省略该列,或使用 DEFAULT 关键字来完成。

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

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

注意

在 PostgreSQL 7.3 之前,serial 隐含 UNIQUE。现在这不再是自动的。如果你希望 serial 列是 UNIQUE 或 PRIMARY KEY,就必须像对其他数据类型一样显式指定。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.