天天看点

PostgreSQL 数据类型

本章节,我们将讨论 PostgreSQL 的数据类型,数据类型是我们在创建表的时候为每个字段设置的。

设置数据类型的好处:

PostgreSQL提 供了丰富的数据类型。用户可以使用 CREATE TYPE 命令在数据库中创建新的数据类型。PostgreSQL 的数据类型有很多种,下面我们具体来说明。

数值类型由 2 字节、4 字节或 8 字节的整数以及 4 字节或 8 字节的浮点数和可选精度的十进制数组成。

下表列出了可用的数值类型。

名字

存储长度

描述

范围

smallint

2 字节

小范围整数

-32768 到 +32767

integer

4 字节

常用的整数

-2147483648 到 +2147483647

bigint

8 字节

大范围整数

-9223372036854775808 到 +9223372036854775807

decimal

可变长

用户指定的精度,精确

小数点前 131072 位;小数点后 16383 位

numeric

real

可变精度,不精确

6 位十进制数字精度

double precision

15 位十进制数字精度

smallserial

自增的小范围整数

1 到 32767

serial

自增整数

1 到 2147483647

bigserial

自增的大范围整数

1 到 9223372036854775807

money 类型存储带有固定小数精度的货币金额。

numeric、int 和 bigint 类型的值可以转换为 money,不建议使用浮点数来处理处理货币类型,因为存在舍入错误的可能性。

存储容量

money

货币金额

-92233720368547758.08 到 +92233720368547758.07

下表列出了 PostgreSQL 所支持的字符类型:

序号

名字 & 描述

1

<b>character varying(n), varchar(n)</b>

变长,有长度限制

2

<b>character(n), char(n)</b>

f定长,不足补空白

3

<b>text</b>

变长,无长度限制

下表列出了 PostgreSQL 支持的日期和时间类型。

存储空间

最低值

最高值

分辨率

timestamp [ (p) ] [ without time zone ]

日期和时间(无时区)

4713 BC

294276 AD

1 毫秒 / 14 位

timestamp [ (p) ] with time zone

日期和时间,有时区

date

只用于日期

5874897 AD

1 天

time [ (p) ] [ without time zone ]

只用于一日内时间

00:00:00

24:00:00

time [ (p) ] with time zone

12 字节

只用于一日内时间,带时区

00:00:00+1459

24:00:00-1459

interval [ fields ] [ (p) ]

时间间隔

-178000000 年

178000000 年

PostgreSQL 支持标准的 boolean 数据类型。

boolean 有"true"(真)或"false"(假)两个状态, 第三种"unknown"(未知)状态,用 NULL 表示。

名称

存储格式

boolean

1 字节

true/false

枚举类型是一个包含静态和值的有序集合的数据类型。

PostgtesSQL中的枚举类型类似于 C 语言中的 enum 类型。

与其他类型不同的是枚举类型需要使用 CREATE TYPE 命令创建。

创建一周中的几天,如下所示:

就像其他类型一样,一旦创建,枚举类型可以用于表和函数定义。

几何数据类型表示二维的平面物体。

下表列出了 PostgreSQL 支持的几何类型。

最基本的类型:点。它是其它类型的基础。

说明

表现形式

point

16 字节

平面中的点

(x,y)

line

32 字节

(无穷)直线(未完全实现)

((x1,y1),(x2,y2))

lseg

(有限)线段

box

矩形

path

16+16n 字节

闭合路径(与多边形类似)

((x1,y1),...)

开放路径

[(x1,y1),...]

polygon

40+16n 字节

多边形(与闭合路径相似)

circle

24 字节

&lt;(x,y),r&gt; (圆心和半径)

PostgreSQL 提供用于存储 IPv4 、IPv6 、MAC 地址的数据类型。

用这些数据类型存储网络地址比用纯文本类型好, 因为这些类型提供输入错误检查和特殊的操作和功能。

cidr

7 或 19 字节

IPv4 或 IPv6 网络

inet

IPv4 或 IPv6 主机和网络

macaddr

6 字节

MAC 地址

在对 inet 或 cidr 数据类型进行排序的时候, IPv4 地址总是排在 IPv6 地址前面,包括那些封装或者是映射在 IPv6 地址里的 IPv4 地址, 比如 ::10.2.3.4 或 ::ffff:10.4.3.2。

位串就是一串 1 和 0 的字符串。它们可以用于存储和直观化位掩码。 我们有两种 SQL 位类型:bit(n) 和bit varying(n), 这里的n是一个正整数。

bit 类型的数据必须准确匹配长度 n, 试图存储短些或者长一些的数据都是错误的。bit varying 类型数据是最长 n 的变长类型;更长的串会被拒绝。 写一个没有长度的bit 等效于 bit(1), 没有长度的 bit varying 意思是没有长度限制。

全文检索即通过自然语言文档的集合来找到那些匹配一个查询的检索。

PostgreSQL 提供了两种数据类型用于支持全文检索:

<b>tsvector</b>

tsvector 的值是一个无重复值的 lexemes 排序列表, 即一些同一个词的不同变种的标准化。

<b>tsquery</b>

tsquery 存储用于检索的词汇,并且使用布尔操作符 &amp;(AND),|(OR)和!(NOT) 来组合它们,括号用来强调操作符的分组。

uuid 数据类型用来存储 RFC 4122,ISO/IEF 9834-8:2005 以及相关标准定义的通用唯一标识符(UUID)。 (一些系统认为这个数据类型为全球唯一标识符,或GUID。) 这个标识符是一个由算法产生的 128 位标识符,使它不可能在已知使用相同算法的模块中和其他方式产生的标识符相同。 因此,对分布式系统而言,这种标识符比序列能更好的提供唯一性保证,因为序列只能在单一数据库中保证唯一。

UUID 被写成一个小写十六进制数字的序列,由分字符分成几组, 特别是一组8位数字+3组4位数字+一组12位数字,总共 32 个数字代表 128 位, 一个这种标准的 UUID 例子如下:

xml 数据类型可以用于存储XML数据。 将 XML 数据存到 text 类型中的优势在于它能够为结构良好性来检查输入值, 并且还支持函数对其进行类型安全性检查。 要使用这个数据类型,编译时必须使用 configure --with-libxml。

xml 可以存储由XML标准定义的格式良好的"文档", 以及由 XML 标准中的 XMLDecl? content 定义的"内容"片段, 大致上,这意味着内容片段可以有多个顶级元素或字符节点。 xmlvalue IS DOCUMENT 表达式可以用来判断一个特定的 xml 值是一个完整的文件还是内容片段。

使用函数 xmlparse: 来从字符数据产生 xml 类型的值:

json 数据类型可以用来存储 JSON(JavaScript Object Notation)数据, 这样的数据也可以存储为 text,但是 json 数据类型更有利于检查每个存储的数值是可用的 JSON 值。

此外还有相关的函数来处理 json 数据:

实例

实例结果

array_to_json('{{1,5},{99,100}}'::int[])

[[1,5],[99,100]]

row_to_json(row(1,'foo'))

{"f1":1,"f2":"foo"}

PostgreSQL 允许将字段定义成变长的多维数组。

数组类型可以是任何基本类型或用户定义类型,枚举类型或复合类型。

创建表的时候,我们可以声明数组,方式如下:

pay_by_quarter 为一维整型数组、schedule 为二维文本类型数组。

我们也可以使用 "ARRAY" 关键字,如下所示:

插入值使用花括号 {},元素在 {} 使用逗号隔开:

现在我们可以在这个表上运行一些查询。

首先,我们演示如何访问数组的一个元素。 这个查询检索在第二季度薪水变化的雇员名:

数组的下标数字是写在方括弧内的。

我们可以对数组的值进行修改:

或者使用 ARRAY 构造器语法:

要搜索一个数组中的数值,你必须检查该数组的每一个值。

比如:

另外,你可以用下面的语句找出数组中所有元素值都等于 10000 的行:

或者,可以使用 generate_subscripts 函数。例如:

复合类型表示一行或者一条记录的结构; 它实际上只是一个字段名和它们的数据类型的列表。PostgreSQL 允许像简单数据类型那样使用复合类型。比如,一个表的某个字段可以声明为一个复合类型。

下面是两个定义复合类型的简单例子:

语法类似于 CREATE TABLE,只是这里只可以声明字段名字和类型。

定义了类型,我们就可以用它创建表:

要以文本常量书写复合类型值,在圆括弧里包围字段值并且用逗号分隔他们。 你可以在任何字段值周围放上双引号,如果值本身包含逗号或者圆括弧, 你必须用双引号括起。

复合类型常量的一般格式如下:

一个例子是:

要访问复合类型字段的一个域,我们写出一个点以及域的名字, 非常类似从一个表名字里选出一个字段。实际上,因为实在太像从表名字中选取字段, 所以我们经常需要用圆括弧来避免分析器混淆。比如,你可能需要从on_hand 例子表中选取一些子域,像下面这样:

这样将不能工作,因为根据 SQL 语法,item是从一个表名字选取的, 而不是一个字段名字。你必须像下面这样写:

或者如果你也需要使用表名字(比如,在一个多表查询里),那么这么写:

现在圆括弧对象正确地解析为一个指向item字段的引用,然后就可以从中选取子域。

范围数据类型代表着某一元素类型在一定范围内的值。

例如,timestamp 范围可能被用于代表一间会议室被预定的时间范围。

PostgreSQL 内置的范围类型有:

int4range — integer的范围

int8range —bigint的范围

numrange —numeric的范围

tsrange —timestamp without time zone的范围

tstzrange —timestamp with time zone的范围

daterange —date的范围

此外,你可以定义你自己的范围类型。

范围值的输入必须遵循下面的格式:

圆括号或者方括号显示下边界和上边界是不包含的还是包含的。注意最后的格式是 空,代表着一个空的范围(一个不含有值的范围)。

PostgreSQL 在内部使用对象标识符(OID)作为各种系统表的主键。

同时,系统不会给用户创建的表增加一个 OID 系统字段(除非在建表时声明了WITH OIDS 或者配置参数default_with_oids设置为开启)。oid 类型代表一个对象标识符。除此以外 oid 还有几个别名:regproc, regprocedure, regoper, regoperator, regclass, regtype, regconfig, 和regdictionary。

引用

数值例子

oid

任意

数字化的对象标识符

564182

regproc

pg_proc

函数名字

sum

regprocedure

带参数类型的函数

sum(int4)

regoper

pg_operator

操作符名

+

regoperator

带参数类型的操作符

*(integer,integer) 或 -(NONE,integer)

regclass

pg_class

关系名

pg_type

regtype

数据类型名

regconfig

pg_ts_config

文本搜索配置

english

regdictionary

pg_ts_dict

文本搜索字典

simple

PostgreSQL类型系统包含一系列特殊用途的条目, 它们按照类别来说叫做伪类型。伪类型不能作为字段的数据类型, 但是它可以用于声明一个函数的参数或者结果类型。 伪类型在一个函数不只是简单地接受并返回某种SQL 数据类型的情况下很有用。

下表列出了所有的伪类型:

any

表示一个函数接受任何输入数据类型。

anyelement

表示一个函数接受任何数据类型。

anyarray

表示一个函数接受任意数组数据类型。

anynonarray

表示一个函数接受任意非数组数据类型。

anyenum

表示一个函数接受任意枚举数据类型。

anyrange

表示一个函数接受任意范围数据类型。

cstring

表示一个函数接受或者返回一个空结尾的 C 字符串。

internal

表示一个函数接受或者返回一种服务器内部的数据类型。

language_handler

一个过程语言调用处理器声明为返回language_handler。

fdw_handler

一个外部数据封装器声明为返回fdw_handler。

record

标识一个函数返回一个未声明的行类型。

trigger

一个触发器函数声明为返回trigger。

void

表示一个函数不返回数值。

opaque

一个已经过时的类型,以前用于所有上面这些用途。

更多内容参考:PostgreSQL 数据类型