Chapter 5. 数据类型

Table of Contents
5.1. 数值类型
5.1.1. 整数类型
5.1.2. 任意精度数据
5.1.3. 浮点数类型
5.1.4. Serial(序列)类型
5.2. 货币类型
5.3. 字符类型
5.4. 二进制字串
5.5. 日期/时间类型
5.5.1. 日期/时间输入
5.5.2. 日期/时间输出
5.5.3. 时区
5.5.4. 内部
5.6. 布尔类型
5.7. 几何类型
5.7.1. Point(点)
5.7.2. 线段
5.7.3. Box(方)
5.7.4. Path(路径)
5.7.5. Polygon(多边形)
5.7.6. Circle(圆)
5.8. 网络地址数据类型
5.8.1. inet
5.8.2. cidr
5.8.3. inetcidr 对比
5.8.4. macaddr
5.9. 位串类型
5.10. 对象标识符类型
5.11. 伪类型
5.12. 数组

PostgreSQL 有着丰富的数据类型可用. 用户可以使用 CREATE TYPE命令为 PostgreSQL 增加新的数据类型.

Table 5-1 显示了所有包含在标准版本里的 普通数据类型.在"别名"列里列出的大多数可选名字 都是因历史原因 PostgreSQL 在内部使用的 名字.另外,还有一些内部使用的或者废弃的类型也可以用, 但没有在这里列出.

Table 5-1. 数据类型

类型名字别名描述
bigintint8有符号 8 字节整数
bigserialserial8自增八字节整数
bit 定长位串
bit varying(n)varbit(n)变长位串
booleanbool逻辑布尔量 (真/假)
box 二维平面中的长方形
bytea 二进制数据
character(n)char(n)定长字符串
character varying(n)varchar(n)变长字符串
cidr IP 网络地址
circle 二维平面中的圆
date 日历日期(年,月,日)
double precisionfloat8双精度浮点数字
inet IP 网络或主机地址
integerintint4四字节长有符号整数
interval(p) 通用的时间间隔
line 二维平面中的无限长直线(没实现)
lseg 二维平面中的线段
macaddr MAC 地址
money 货币金额
numeric [ (p, s) ]decimal [ (p, s) ]可选精度的准确数字
path 二维平面的开放的或封闭的几何路径
point 二维平面中的点
polygon 二维平面中的封闭几何路径
realfloat4单精度浮点数
smallintint2有符号两字节整数
serialserial4自增四字节整数
text 变长字符串
time [ (p) ] [ without time zone ] 一天里的时间
time [ (p) ] with time zonetimetz一天里的时间,包括时区
timestamp [ (p) ] without time zonetimestamp日期和时间
timestamp [ (p) ] [ with time zone ]timestamptz日期和时间

兼容性: 下列类型(或者那样拼写的)是SQL声明的: bitbit varyingbooleancharcharactercharacter varyingvarchardatedouble precisionintegerintervalnumericdecimalrealsmallinttimetimestamp (包括有时区和无时区的).

每种数据类型都有一个由其输入和输出函数决定的外部表现形式. 许多内建的类型有明显的格式.不过,许多类型要么是 PostgreSQL 所特有的,比如开放和 闭合路径,要么是有几种不同的格式可能,比如日期和时间类型. 绝大多数与基本类型(如:整数和浮点数)对应的输入输出函数都会做错误检查. 出于改善执行性能的考虑, 有些输入和输出函数是不可逆的.也就是说,输出函数的输出结果和 原始的输入比较的时候可能丢失精度.

一些操作符和函数(如加法和乘法)并不做运行时的错误检查. 因而在一些系统上的对某些数据类型的数字操 作会导致轻微的数值溢出或下溢。

5.1. 数值类型

数值类型由2 ,4或8字节的整数以及4或8字节的浮点数和固定精度小数组成。 Table 5-2 列出了所有可用类型。

Table 5-2. 数值类型

数值类型存储空间描述范围
smallint2 字节小范围固定精度-32768 到 +32767
integer4 字节常用的固定精度数-2147483648 到 +2147483647
bigint8 字节大范围的固定精度数字-9223372036854775808 到 9223372036854775807
decimal变长用户声明精度,精确无限制
numeric变长用户声明精度,精确无限制
real4 字节变精度,不精确6 位十进制数字精度
double precision8 字节变精度,不精度15 位十进制数字精度
serial4 字节自增整数1 到 +2147483647
bigserial8 字节大范围的自增整数1 到 9223372036854775807

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

5.1.1. 整数类型

类型 smallintintegerbigint 存储各种范围的全部是数字的数,也就是没有小数部分的数字. 试图存储超出范围以外的数值将导致一个错误.

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

bigint 类型可能不是在所有平台上都运转正确, 因为它依赖编译器对八字节整数的支持.在那些没有这样支持的机器上, bigint 的作用和 integer 一样(但是仍然占据 八字节存储).不过,我们还不知道任何有这样的情况的平台.

SQL只声明了整数类型 integer(或int)和 smallint.类型 bigint,和类型名 int2int4,和 int8 都是扩展, 也在许多其它 RDBMS 产品中使用.

注意: 如果你有一个有索引的 smallint 或者 bigint 字段,那么你可能在让系统使用这些索引的时候碰到 麻烦.比如,象下面这样形式的子句

... WHERE smallint_column = 42

将不会使用索引,因为系统给常量 42 赋予了 integer 类型, 而目前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.也就是转化成整数精度. 我们觉得这样做有点没用. 如果你关心移植性,那你最好总是明确声明精度和比例.)

如果一个数值的精度或者比例比字段声明的精度或者比例高, 那么系统将尝试园整该数值.如果该数值无法做这样的园整以满足 声明的限制,那么抛出一个错误.

类型 decimalnumeric 是等效的. 两种类型都是SQL标准.

5.1.3. 浮点数类型

数据类型 realdouble precision 是不准确的,变精度的数字类型. 实际上,这些类型是 IEEE 标准 754 二进制浮点数算术 (分别对应单和双精度)的一般实现,加上下层处理器,操作系统和 编译器对它的支持.

不准确意味着一些数值不能准确地转换成内部格式并且是以近似的形式 存储的,因此存储然后把数据再打印出来可能显示一些缺失. 处理这些错误以及这些错误是如何在计算中传播的属于数学和计算机 科学的一个完整的分支,我们不会在这里进一步讨论它,这里的讨论仅限 于如下几点∶

  • 如果你要求准确的计算(比如计算货币金额),应使用 numeric 类型.

  • 如果你想用这些类型类型做任何重要的复杂计算,尤其是那些你 对范围情况(无穷,下溢)严重依赖的事情,那你应该仔细评诂你的实现.

  • 拿两个浮点数值进行相等性比较可能象,也可能不象想像那样运转.

通常,real 类型的范围是至少 -1E+37 到 +1E+37, 精度至少是 6 位小数.double precision 类型通常有 -1E+308 到 +1E+308 的范围,精度是至少 15 位数字.太大或者太小的 数值都会导致错误.如果输入数据太高,那么可能发生园整.太接近 零的数字,如果无法与零值的表现形式相区分就会产生下溢错.

5.1.4. Serial(序列)类型

serial 类型不是真正的类型, 只是为在表中设置唯一标识做的概念上的便利. 在目前的实现中,下面一句话:

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 来实现。

类型名 serialserial4 是等效的∶ 两个都创建 integer 字段.类型名 bigserialserial8 也一样,只不过它创建一个 bigint 字段.如果你预计在表的生存期中使用的标识数目 超过 231 个,那么你应该使用 bigserial

一个 serial 类型创建的序列在所属的字段被删除的时候 自动删除,否则是不会被删除的。(这一点在 PostgreSQL 版本 7.3 之前可不是真的。请注意,这种自动删除的关联在通过重载 7.3 以前的 数据库转储的时候可不会自动发生;那样的转储文件不包含需要建立这种关联 关系的信息。) 另外,这样的序列和字段之间的依赖性只在 serial 字段本身上有; 如果任何其它字段引用了序列(可能是手工调用 nextval() 函数), 那么,如果这个序列被删除了,它们就会被破坏。我们认为这样使用 serial 字段是一种不好的形式。

注意: PostgreSQL 7.3 之前,serial 隐含 UNIQUE。但现在不再是自动隐含的了。如果你希望 一个序列字段是 UNIQUE 或者是 PRIMARY KEY, 那么现在你必须声明它,和其他数据类型一样。