pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
目录
PostgreSQL 提供了丰富的原生数据类型。 用户可以使用CREATE TYPE命令向 PostgreSQL添加新类型。
表 8.1 列出了所有内建的通用数据类型。“别名”列中列出的大多数替代名称,是 PostgreSQL 出于历史原因在内部使用的名称。此外还有一些内部使用或已废弃的类型可用,但这里没有列出。
表 8.1. 数据类型
| 名字 | 别名 | 描述 |
|---|---|---|
bigint |
int8 |
有符号的8字节整数 |
bigserial |
serial8 |
自动递增的8字节整数 |
bit |
定长位串 | |
bit varying( |
varbit( |
变长位串 |
boolean |
bool |
逻辑布尔值(真/假) |
box |
平面上的矩形框 | |
bytea |
二进制数据 | |
character varying( |
varchar( |
变长字符串 |
character( |
char( |
定长字符串 |
cidr |
IPv4或IPv6网络地址 | |
circle |
平面上的圆 | |
date |
日历日期(年、月、日) | |
double precision |
float8 |
双精度浮点数 |
inet |
IPv4或IPv6主机地址 | |
integer |
int, int4 |
有符号4字节整数 |
interval( |
时间段 | |
line |
平面上的无限直线(未完全实现) | |
lseg |
平面上的线段 | |
macaddr |
MAC 地址 | |
money |
货币数量 | |
numeric [ ( |
decimal [ ( |
精度可选择的精确数值 |
path |
平面上的开放和闭合几何路径 | |
point |
平面上的几何点 | |
polygon |
平面上的封闭几何路径 | |
real |
float4 |
单精度浮点数 |
smallint |
int2 |
有符号2字节整数 |
serial |
serial4 |
自动递增的4字节整数 |
text |
变长字符串 | |
time [ ( |
一天中的时间 | |
time [ ( |
timetz |
一天中的时间,包括时区 |
timestamp [ ( |
timestamp |
日期和时间 |
timestamp [ ( |
timestamptz |
日期和时间,包括时区 |
下列类型(或它们的这些拼写形式)由SQL规定:bit、bit varying、boolean、char、character varying、character、varchar、date、double precision、integer、interval、numeric、decimal、real、smallint、time(有时区或无时区)、timestamp(有时区或无时区)。
每种数据类型都有由其输入和输出函数决定的外部表示。许多内建类型都有显而易见的外部格式。但也有一些类型要么为 PostgreSQL 所独有(例如开放和闭合路径),要么有多种可选格式(例如日期和时间类型)。 有些输入和输出函数是不可逆的。也就是说,输出函数的结果与原始输入相比可能损失精度。
为了提高执行速度,某些运算符和函数(例如加法和乘法)不做运行时错误检查。例如在某些系统上,某些数据类型的数值运算符可能静默地导致下溢或上溢。
数值类型包括二字节、四字节和八字节整数,四字节和八字节浮点数,以及固定精度的小数。表 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 章。下面的几节详细描述这些类型。
类型 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'
这会使系统推迟类型解析,从而为常量指派正确的类型。
numeric 类型最多可存储 1000 位精度的数字并精确执行计算。特别推荐用它存储货币金额和其他要求精确的数量。但与下一节描述的浮点类型相比,numeric 类型非常慢。
下面使用如下术语:numeric的小数位数是小数部分中十进制数字的数量,即小数点右侧的位数。numeric的精度是整个数中有效数字的总数,即小数点两侧的数字位数之和。因此,数值 23.5141 的精度为 6,小数位数为 4。整数可以视为小数位数为零。
numeric 类型的精度和小数位数都可以配置。要声明一个 numeric 类型的列,可使用如下语法
NUMERIC(precision,scale)
精度必须为正,小数位数为零或正。也可以
NUMERIC(precision)
选择小数位数 0。指定
NUMERIC
而不带任何精度和小数位数,则会创建一个可以存储任意精度和小数位数的数值的列,精度上限为实现限制。这种列不会把输入值强制转换为任何特定的小数位数,而声明了小数位数的 numeric 列会把输入值强制转换为该小数位数。(SQL 标准要求默认小数位数为 0,即强制转换为整数精度。我们觉得这没什么用处。如果你关心可移植性,就总是显式指定精度和小数位数。)
如果一个值的精度或小数位数大于列所声明的精度或小数位数,系统会尝试对该值四舍五入。如果无法通过四舍五入满足声明的限制,则会引发一个错误。
类型decimal和numeric是等效的。两种类型都是SQL标准的一部分。
数据类型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(中的精度被理解为这么多位十进制数字。现在这一点已被纠正,以符合 SQL 标准,即精度以二进制位来衡量。假定p)real和double precision的尾数分别恰好有 24 位和 53 位,对于 IEEE 标准浮点实现而言是正确的。在非 IEEE 平台上可能会有少许偏差,但为简单起见,所有平台都使用相同的p取值范围。
serial和bigserial并不是真正的数据类型,它们只是为了创建唯一标识符列而提供的记法便利(类似于其他一些数据库支持的AUTO_INCREMENT属性)。在当前实现中,下列语句:
CREATE TABLEtablename(colnameSERIAL );
等效于指定:
CREATE SEQUENCEtablename_colname_seq; CREATE TABLEtablename(colnameinteger 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 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。