PostgreSQL还有很多数据类型,例如枚举类型、几何类型、网络地址和MAC地址类型、XML类型、JSON类型、数组类型、范围(range)类型、复合数据类型、组合类型、对象标识符等。复合数据类型等价于其他数据库自定义数据类型。
首先介绍枚举类型。
---创建weekday枚举
postgres=# create type weekday as enum('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday');
CREATE TYPE
---查看枚举weekday信息
postgres=# \dT+
数据类型列表
架构模式 | 名称 | 内部名称 | 大小 | 成员 | 拥有者 | 存取权限 | 描述
----------+---------+----------+------+-----------+----------+----------+------
public | weekday | weekday | 4 | Monday +| postgres | |
| | | | Tuesday +| | |
| | | | Wednesday+| | |
| | | | Thursday +| | |
| | | | Friday +| | |
| | | | Saturday +| | |
| | | | Sunday | | |
(1 行记录)
---另一种查询枚举方法
postgres=# select * from pg_enum;
enumtypid | enumsortorder | enumlabel
-----------+---------------+-----------
16486 | 1 | Monday
16486 | 2 | Tuesday
16486 | 3 | Wednesday
16486 | 4 | Thursday
16486 | 5 | Friday
16486 | 6 | Saturday
16486 | 7 | Sunday
(7 行记录)
postgres=#
---演示插入数据
postgres=# create table testweekday(id int,week weekday);
CREATE TABLE
postgres=# insert into testweekday values(1,'Sunday'),(2,'Monday');
INSERT 0 2
postgres=#
PostgreSQL枚举类型类似于C#枚举数据类型,用户输入数据必须符合已有数据,无法输入其他值。枚举类型输入值区分大小写,错误输入会导致错误发生。
枚举类型字段可以在表列内比较大小,例如
postgres=# insert into testweekday values(3,'Tuesday'),(4,'Thursday');
INSERT 0 2
postgres=# select week from testweekday;
week
----------
Sunday
Monday
Tuesday
Thursday
(4 行记录)
postgres=# select min(week),count(week) from testweekday;
min | count
--------+-------
Monday | 4
(1 行记录)
postgres=#
PostgreSQL支持二维几何数据类型,采用笛卡尔坐标系。如点、直线、线段、矩形和圆等。虚数、极坐标、张量等都是复合数据类型。
postgres=# create table testgeometry(testpoint point,testline line,testbox box);
CREATE TABLE
postgres=# insert into testgeometry(testpoint,testline,testbox) values('(1,0)',null,null),(null,'((1,2),(2,2))',null),(null,null,'((0,0),(1,1))');
INSERT 0 3
postgres=#
[]表示开放路径,()表示闭合路径。闭合路径成环。
PostgreSQL网络地址数据类型cidr和inet支持IPv4和和IPv6数据类型,MAC地址数据类型macaddr支持MAC地址。
postgres=# create table networkaddress(testcidr cidr,testinet inet);
CREATE TABLE
postgres=#
postgres=# insert into networkaddress values('192.168.0.0/24','192.168.0.0/24');
INSERT 0 1
postgres=# insert into networkaddress values('192.168.0.0/16','192.168.0.0/16');
INSERT 0 1
postgres=# insert into networkaddress values('192.168.0.0/16','192.168.0.0/8');
INSERT 0 1
postgres=# insert into networkaddress values('192.168.0.1','192.168.0.1');
INSERT 0 1
postgres=# select testcidr,testinet from networkaddress;
testcidr | testinet
----------------+----------------
192.168.0.0/24 | 192.168.0.0/24
192.168.0.0/16 | 192.168.0.0/16
192.168.0.0/16 | 192.168.0.0/8
192.168.0.1/32 | 192.168.0.1
(4 行记录)
postgres=#
根据测试数据输入结果可知,cidr和inet子网掩码均可省略,需要注意IPv4子网掩码书写方式为纯数字,范围为0-32。IPv6子网掩码范围为0-128。两者区别在于cidr会检查输入值正确性,输出时带子网掩码。
postgres=# insert into networkaddress values('192.168.0/16','192.168.0/16');
INSERT 0 1
---第二个值子网掩码错误
postgres=# insert into networkaddress values('192.168.0/16','192.168.0/1');
INSERT 0 1
postgres=# select testcidr,testinet from networkaddress;
testcidr | testinet
----------------+----------------
192.168.0.0/24 | 192.168.0.0/24
192.168.0.0/16 | 192.168.0.0/16
192.168.0.0/16 | 192.168.0.0/8
192.168.0.1/32 | 192.168.0.1
192.168.0.0/16 | 192.168.0.1
192.168.0.0/16 | 192.168.0.0/16
192.168.0.0/16 | 192.168.0.0/1
(6 行记录)
postgres=#
---错误写法
---postgres=# insert into networkaddress values('192.168.0/16','192.168.0');
输入数据可以不写完全。注意对比错误写法和正确写法区别,对比查询结果。
macaddr储存子网掩码地址,子网掩码是16进制字符,长度为8位,可以接受分段和分隔符,分隔符可以是:或-,可以省略不写。例如00-00-00-00-00-C0每两个字符分段一次,以-作为分隔符,分割长度可以为2、4、6、和8。-和:分隔符长度可以是2和6。.作为分隔符只支持类似0000.0000.00C0格式。
postgres=# create table testmacaddress(testmacaddr macaddr);
CREATE TABLE
postgres=# insert into testmacaddress values('00-00-00-00-00-C0'),('00-00-00-00-00-c1');
INSERT 0 2
postgres=# insert into testmacaddress values('0000-0000-00C0'),('00-00-00-00-00-c1');
INSERT 0 2
postgres=# insert into testmacaddress values('000000-0000C0'),('00-00-00-00-00-c1');
INSERT 0 2
postgres=# insert into testmacaddress values('0000.0000.00C0'),('00-00-00-00-00-c1');
INSERT 0 2
postgres=# insert into testmacaddress values('0000.0000.00C0'),('00-00-00-00-00-c1');
INSERT 0 2
postgres=# select * from testmacaddress;
testmacaddr
-------------------
00:00:00:00:00:c0
00:00:00:00:00:c1
00:00:00:00:00:c0
00:00:00:00:00:c1
00:00:00:00:00:c0
00:00:00:00:00:c1
00:00:00:00:00:c0
00:00:00:00:00:c1
00:00:00:00:00:c0
00:00:00:00:00:c1
(10 行记录)
postgres=#
推荐:2位长度分隔或无符号分隔。
XML类型、JSON类型、数组类型、范围(range)类型、复合数据类型、组合类型、对象标识符等本文不再加以介绍。