PostgreSQL - 数据类型


在本章中,我们将讨论 PostgreSQL 中使用的数据类型。创建表时,为每一列指定数据类型,即要在表字段中存储什么类型的数据。

这带来了几个好处 -

  • 一致性- 对相同数据类型的列的操作给出一致的结果,并且通常是最快的。

  • 验证- 数据类型的正确使用意味着数据的格式验证和拒绝数据类型范围之外的数据。

  • 紧凑性- 由于列可以存储单一类型的值,因此它以紧凑的方式存储。

  • 性能- 正确使用数据类型可以实现最有效的数据存储。可以快速处理存储的值,从而提高性能。

PostgreSQL 支持多种数据类型。此外,用户可以使用CREATE TYPE SQL 命令创建自己的自定义数据类型。PostgreSQL 中有不同类别的数据类型。下面讨论它们。

数字类型

数字类型由两字节、四字节和八字节整数、四字节和八字节浮点数以及可选择精度的小数组成。下表列出了可用的类型。

姓名 存储大小 描述 范围
小整数 2字节 小范围整数 -32768 至 +32767
整数 4字节 整数的典型选择 -2147483648 至 +2147483647
大整数 8字节 大范围整数 -9223372036854775808 至 9223372036854775807
小数 多变的 用户指定的精度,精确 小数点前最多 131072 位;小数点后最多 16383 位
数字 多变的 用户指定的精度,精确 小数点前最多 131072 位;小数点后最多 16383 位
真实的 4字节 精度可变,不精确 6 位小数精度
双精度 8字节 精度可变,不精确 15 位小数精度
小串行 2字节 小自动递增整数 1 至 32767
连续剧 4字节 自动递增整数 1至2147483647
大连载 8字节 大的自动递增整数 1 至 9223372036854775807

货币类型

货币类型存储具有固定小数精度货币金额。numeric、int 和 bigint数据类型的值可以转换为Money。由于可能出现舍入错误,因此不建议使用浮点数来处理资金。

姓名 存储大小 描述 范围
8字节 货币金额 -92233720368547758.08 至 +92233720368547758.07

字符类型

下表列出了 PostgreSQL 中可用的通用字符类型。

S. 编号 名称和描述
1

字符变化(n)、varchar(n)

有限制的变长

2

字符(n),字符(n)

固定长度,空白填充

3

文本

可变无限长度

二进制数据类型

bytea数据类型允许存储二进制字符串如下表所示。

姓名 存储大小 描述
字节茶 1 或 4 个字节加上实际的二进制字符串 变长二进制字符串

日期/时间类型

PostgreSQL 支持一整套 SQL 日期和时间类型,如下表所示。日期是根据公历计算的。这里,除了日期类型,其分辨率为day之外,所有类型的分辨率均为1 微秒/14 位

姓名 存储大小 描述 低价值 高价值
时间戳 [(p)] [无时区] 8字节 日期和时间(无时区) 公元前 4713 年 公元294276年
时间戳 8字节 日期和时间,以及时区 公元前 4713 年 公元294276年
日期 4字节 日期(没有一天中的时间) 公元前 4713 年 公元5874897
时间 [ (p)] [ 无时区 ] 8字节 一天中的时间(无日期) 00:00:00 24:00:00
时间 [ (p)] 与时区 12字节 仅一天中的某些时间,带有时区 00:00:00+1459 24:00:00-1459
间隔 [字段] [(p) ] 12字节 时间间隔 -17800万年 17800万年

布尔类型

PostgreSQL 提供标准 SQL 类型 Boolean。布尔数据类型可以具有状态truefalse和第三种状态known,该状态由SQL null 值表示。

姓名 存储大小 描述
布尔值 1字节 真或假的状态

枚举类型

枚举 (enum) 类型是包含静态、有序值集的数据类型。它们相当于许多编程语言中支持的枚举类型。

与其他类型不同,枚举类型需要使用 CREATE TYPE 命令创建。该类型用于存储静态、有序的值集。例如罗盘方向,即北、南、东、西或一周中的几天,如下所示 -

CREATE TYPE week AS ENUM ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');

枚举一旦创建,就可以像任何其他类型一样使用。

几何型

几何数据类型表示二维空间对象。最基本的类型,即点,构成了所有其他类型的基础。

姓名 存储大小 表示 描述
观点 16字节 平面上的点 (x,y)
线 32字节 无限线(未完全实现) ((x1,y1),(x2,y2))
LSEG 32字节 有限线段 ((x1,y1),(x2,y2))
盒子 32字节 长方形盒子 ((x1,y1),(x2,y2))
小路 16+16n字节 闭合路径(类似于多边形) ((x1,y1),...)
小路 16+16n字节 开放路径 [(x1,y1),...]
多边形 40+16n 多边形(类似于闭合路径) ((x1,y1),...)
圆圈 24字节 圆圈 <(x,y),r>(中心点和半径)

网络地址类型

PostgreSQL 提供了存储 IPv4、IPv6 和 MAC 地址的数据类型。最好使用这些类型而不是纯文本类型来存储网络地址,因为这些类型提供输入错误检查以及专门的运算符和函数。

姓名 存储大小 描述
西德 7 或 19 字节 IPv4 和 IPv6 网络
内网 7 或 19 字节 IPv4 和 IPv6 主机和网络
麦克地址 6字节 MAC地址

位串类型

位字符串类型用于存储位掩码。它们是 0 或 1。有两种 SQL 位类型:bit(n)bit Varying(n),其中 n 是正整数。

文本搜索类型

此类型支持全文搜索,这是搜索自然语言文档集合以查找与查询最匹配的文档的活动。有两种数据类型 -

S. 编号 名称和描述
1

ts向量

这是不同单词的排序列表,这些单词已被标准化以合并同一单词的不同变体,称为“词位”。

2

tsquery

它存储要搜索的词位,并将它们组合起来以遵循布尔运算符 & (AND)、| (或),并且!(不是)。括号可用于强制对运算符进行分组。

UUID类型

UUID(通用唯一标识符)被写为一系列小写十六进制数字,由连字符分隔成几组,具体来说是一组八位数字,后跟三组四位数字,最后是一组 12 位数,例如总共32位数字代表128位。

UUID 的示例为 - 550e8400-e29b-41d4-a716-446655440000

XML类型

XML数据类型可用于存储XML数据。为了存储 XML 数据,首先必须使用 xmlparse 函数创建 XML 值,如下所示 -

XMLPARSE (DOCUMENT '<?xml version="1.0"?>
<tutorial>
<title>PostgreSQL Tutorial </title>
   <topics>...</topics>
</tutorial>')

XMLPARSE (CONTENT 'xyz<foo>bar</foo><bar>foo</bar>')

JSON 类型

json数据类型可用于存储 JSON(JavaScript 对象表示法)数据此类数据也可以存储为text,但json数据类型的优点是检查每个存储的值是否是有效的 JSON 值。还有相关的支持函数可用,可以直接使用它们来处理 JSON 数据类型,如下所示。

例子 结果示例
array_to_json('{{1,5},{99,100}}'::int[]) [[1,5],[99,100]]
row_to_json(行(1,'foo')) {"f1":1,"f2":"foo"}

数组类型

PostgreSQL 提供了将表的列定义为可变长度多维数组的机会。可以创建任何内置或用户定义的基类型、枚举类型或复合类型的数组。

数组声明

数组类型可以声明为

CREATE TABLE monthly_savings (
   name text,
   saving_per_quarter integer[],
   scheme text[][]
);

或者使用关键字“ARRAY”作为

CREATE TABLE monthly_savings (
   name text,
   saving_per_quarter integer ARRAY[4],
   scheme text[][]
);

插入值

数组值可以作为文字常量插入,将元素值括在花括号内并用逗号分隔。下面显示了一个示例 -

INSERT INTO monthly_savings 
VALUES (‘Manisha’, 
‘{20000, 14600, 23500, 13250}’, 
‘{{“FD”, “MF”}, {“FD”, “Property”}}’); 

访问数组

下面显示了访问数组的示例。下面给出的命令将选择第二季度储蓄比第四季度储蓄更多的人。

SELECT name FROM monhly_savings WHERE saving_per_quarter[2] > saving_per_quarter[4];

修改数组

修改数组的示例如下所示。

UPDATE monthly_savings SET saving_per_quarter = '{25000,25000,27000,27000}'
WHERE name = 'Manisha';

或使用 ARRAY 表达式语法 -

UPDATE monthly_savings SET saving_per_quarter = ARRAY[25000,25000,27000,27000]
WHERE name = 'Manisha';

搜索数组

搜索数组的示例如下所示。

SELECT * FROM monthly_savings WHERE saving_per_quarter[1] = 10000 OR
saving_per_quarter[2] = 10000 OR
saving_per_quarter[3] = 10000 OR
saving_per_quarter[4] = 10000;

如果已知数组的大小,则可以使用上面给出的搜索方法。另外,下面的示例显示了在大小未知时如何进行搜索。

SELECT * FROM monthly_savings WHERE 10000 = ANY (saving_per_quarter);

复合类型

该类型表示字段名称及其数据类型的列表,即表的行或记录的结构。

复合类型的声明

以下示例展示了如何声明复合类型

CREATE TYPE inventory_item AS (
   name text,
   supplier_id integer,
   price numeric
);

此数据类型可用于创建表,如下所示 -

CREATE TABLE on_hand (
   item inventory_item,
   count integer
);

复合值输入

复合值可以作为文字常量插入,将字段值括在括号内并用逗号分隔。下面显示了一个示例 -

INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);

这对于上面定义的inventory_item有效。只要表达式中有多个字段,ROW 关键字实际上是可选的。

访问复合类型

要访问复合列的字段,请使用点后跟字段名称,就像从表名称中选择字段一样。例如,要从 on_hand 示例表中选择一些子字段,查询将如下所示 -

SELECT (item).name FROM on_hand WHERE (item).price > 9.99;

您甚至还可以使用表名称(例如在多表查询中),如下所示 -

SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;

范围类型

范围类型表示使用一定范围数据的数据类型。范围类型可以是离散范围(例如,所有整数值 1 到 10)或连续范围(例如,上午 10:00 到 11:00 之间的任何时间点)。

可用的内置范围类型包括以下范围 -

  • int4range - 整数范围

  • int8range - bigint 的范围

  • numrange - 数字范围

  • tsrange - 没有时区的时间戳范围

  • tstzrange - 带时区的时间戳范围

  • daterange - 日期范围

可以创建自定义范围类型以使新类型的范围可用,例如使用 inet 类型作为基础的 IP 地址范围,或使用 float 数据类型作为基础的浮点范围。

范围类型分别使用 [ ] 和 ( ) 字符支持包含和排除范围边界。例如,“[4,9)”表示从 4 开始(含 4)到 9(不包括 9)的所有整数。

对象标识符类型

对象标识符 (OID) 在 PostgreSQL 内部用作各种系统表的主键。如果指定了WITH OIDS或启用了default_with_oids配置变量,则只有在这种情况下,OID 才会添加到用户创建的表中。下表列出了几种别名类型。除了专门的输入和输出例程外,OID 别名类型没有自己的操作。

姓名 参考 描述 值示例
奥德 任何 数字对象标识符 564182
正则过程 pg_proc 函数名
注册程序 pg_proc 具有参数类型的函数 总和(int4)
雷戈珀 pg_操作符 操作员姓名 +
寄存器操作符 pg_操作符 具有参数类型的运算符 *(整数,整数)或-(无,整数)
注册类 pg_class 关系名称 pg_类型
注册表类型 pg_类型 数据类型名称 整数
注册表配置 pg_ts_config 文本搜索配置 英语
地区词典 pg_ts_dict 文本搜索词典 简单的

伪类型

PostgreSQL 类型系统包含许多特殊用途的条目,统称为伪类型。伪类型不能用作列数据类型,但可用于声明函数的参数或结果类型。

下表列出了现有的伪类型。

S. 编号 名称和描述
1

任何

指示函数接受任何输入数据类型。

2

任何元素

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

3

任意数组

指示函数接受任何数组数据类型。

4

任意非数组

指示函数接受任何非数组数据类型。

5

阿耶努姆

指示函数接受任何枚举数据类型。

6

任意范围

指示函数接受任何范围数据类型。

7

字符串

指示函数接受或返回以 null 结尾的 C 字符串。

8

内部的

指示函数接受或返回服务器内部数据类型。

9

语言处理程序

过程语言调用处理程序被声明为返回 language_handler。

10

fdw_handler

外部数据包装处理程序被声明为返回 fdw_handler。

11

记录

标识返回未指定行类型的函数。

12

扳机

声明触发器函数以返回触发器。

13

空白

表示函数没有返回值。