PostgreSQL基础:部分数据类型

452 阅读5分钟

部分数据类型介绍

精确的小数类型

numeric:可存储最多1000位精度的数字
numeric(m,n):m代表精度(有效数字个数),必须为整数。n代表标度(小数点位数),可以为0或整数
numeric(m):表示标度为0,同numeric(m,0)

例:

postgres=# create table t1(a numeric,b numeric(3,0),c numeric(3,1));
CREATE TABLE
postgres=# insert into t1 values(3.456,3.456,3.456);
INSERT 0 1
postgres=# select * from t1;
   a   | b |  c
-------+---+-----
 3.456 | 3 | 3.5
(1 row)

--当插入的数字精度超过范围,会报错,如下例,插入的"123.456",因为其标度为1,所以总
--的有效位数为小数点前的"123"占了3位加标度1总共为4,查过了精度3,所以报错提示
postgres=# insert into t1 values(3.456,3.456,123.456);
ERROR:  numeric field overflow
DETAIL:  A field with precision 3, scale 1 must round to an absolute value less than 10^2.

--精度需要大于等于标度
postgres=# create table t2(a numeric(2,3));
ERROR:  NUMERIC scale 3 must be between 0 and precision 2
LINE 1: create table t2(a numeric(2,3));

序列类型

PostgreSQL序列类型有serial、bigserial。PG的序列类型实际上是通过序列实现的

postgres=# create table t(id serial,b date);
CREATE TABLE
postgres=# insert into t(b) values(now());
INSERT 0 1
postgres=# insert into t(b) values(now());
INSERT 0 1
postgres=# insert into t(b) values(now());
INSERT 0 1
postgres=# select *from t;
 id |     b
----+------------
  1 | 2021-12-08
  2 | 2021-12-08
  3 | 2021-12-08
(3 rows)

postgres=# \d t
                            Table "public.t"
 Column |  Type   | Collation | Nullable |            Default
--------+---------+-----------+----------+-------------------------------
 id     | integer |           | not null | nextval('t_id_seq'::regclass)
 b      | date    |           |          |

--所以创建序列的语句create table t(id serial,b date);实际等价于:
postgres=# create sequence t_id_seq;
CREATE SEQUENCE
postgres=# create table t(id integer not null default nextval('t_id_seq'));
CREATE TABLE
postgres=# alter sequence t_id_seq owned by t.id;
ALTER SEQUENCE

--创建序列可以指定步长、最大值、最小值等
postgres=# create sequence t_seq increment by 1 minvalue 1 no maxvalue start with 1;
CREATE SEQUENCE

--注:
--INCREMENT BY : 每次序列增加(或减少)的步长
--MINVALUE : 序列最小值,NO MINVALUE表示没有最小值
--MAXVALUE : 序列最大值,NO MAXVALUE表示没有最大值
--START WITH :从什么值开始
--CYCLE : 序列是否循环使用
--OWNED BY : 可以直接指定一个表的字段,也可以不指定

字符串类型

类型名称描述
varchar(n)变长,最大为1GB,varchar(n)为character varying(n)的别名,若不带长度n,表示接受任何长度的字符串
char(n)定长,最大为1GB ,character(n)的别名,未声明长度的character等价于character(1)。
text变长,无长度限制

在其他数据库中,定长char(n)具有一定性能优势,而在PostgreSQL中,定长的char(n),varchar(n)没有差别。所以大多数情况,一般建议使用text和varchar。

枚举类型

枚举类型是一系列有序的静态值集合的一个数据类型,使用枚举类型需要先创建

postgres=# create type week as enum('sun','mon','tues','wed','thur','fri','sat');
CREATE TYPE
postgres=# create table day(a date,b week);
CREATE TABLE
postgres=# insert into day values(date'2021-12-8','wed');
INSERT 0 1
postgres=# insert into day values(date'2021-12-9','thur');
INSERT 0 1
--当不在枚举类型之间,则会报错
postgres=# insert into day values(date'2021-12-9','thuc');
ERROR:  invalid input value for enum week: "thuc"
LINE 1: insert into day values(date'2021-12-9','thuc');

--查看枚举类型定义
postgres=# \dT+
                                      List of data types
 Schema | Name | Internal name | Size | Elements |  Owner   | Access privileges | Description
--------+------+---------------+------+----------+----------+-------------------+-------------
 public | week | week          | 4    | sun     +| postgres |                   |
        |      |               |      | mon     +|          |                   |
        |      |               |      | tues    +|          |                   |
        |      |               |      | wed     +|          |                   |
        |      |               |      | thur    +|          |                   |
        |      |               |      | fri     +|          |                   |
        |      |               |      | sat      |          |                   |
(1 row)

postgres=# select * from pg_enum;
  oid  | enumtypid | enumsortorder | enumlabel
-------+-----------+---------------+-----------
 16480 |     16478 |             1 | sun
 16482 |     16478 |             2 | mon
 16484 |     16478 |             3 | tues
 16486 |     16478 |             4 | wed
 16488 |     16478 |             5 | thur
 16490 |     16478 |             6 | fri
 16492 |     16478 |             7 | sat
(7 rows)

--在枚举类型中,定义的顺序则是值的顺序,所以执行如下语句的结果为:
postgres=# select min(b),max(b) from day;
 min | max
-----+------
 wed | thur
(1 row)

另外,枚举值类型值大小写敏感。

网络地址类型

类型名称存储空间描述
cidr7或19字节IPv4或IPv6的网络地址
inet7或19字节IPv4或IPv6的网络地址或主机地址
macaddr6字节以太网MAC地址

如果子网掩码为32且字节为IPv4,那么inet格式转换后,其代表一个主机地址

postgres=# select '192.168.1.100/32'::inet;
     inet
---------------
 192.168.1.100
(1 row)

cidr总是会显示掩码,并且会检测地址和掩码的关系

postgres=# select '192.168.1.100/32'::cidr;
       cidr
------------------
 192.168.1.100/32
(1 row)
postgres=# select '192.168.1.100/24'::cidr;
ERROR:  invalid cidr value: "192.168.1.100/24"
LINE 1: select '192.168.1.100/24'::cidr;
               ^
DETAIL:  Value has bits set to right of mask.
postgres=# select '192.168.1.0/24'::cidr;
      cidr
----------------
 192.168.1.0/24
(1 row)

macaddr用于存储以太网大的MAC类型,可以接受多种自定义格式

postgres=# select '52:54:00:35:79:44'::macaddr;
      macaddr
-------------------
 52:54:00:35:79:44
(1 row)

复合类型

定义一个复合类型,下例创建了一个person复合类型

postgres=# create type person as(name text , age int, sex boolean);
CREATE TYPE

复合类型的输入

postgres=# create table author(id int, person_info person, book text);
CREATE TABLE
postgres=# insert into author values(1,'("ljy",25,FALSE)','how did');
INSERT 0 1
--可以使用ROW来构造复合类型值
postgres=# insert into author values(2,ROW('pkj',27,TRUE),'i fall');
INSERT 0 1

访问复合类型,需要在字段名称加圆括号

postgres=# select (person_info).name from author;
 name
------
 ljy
 pkj
(2 rows)

复合类型的修改

postgres=# update author set person_info.name='kjpan' where id=2;
UPDATE 1
postgres=# update author set person_info.age=(person_info).age where id=2;
UPDATE 1