PostgreSQL基本操作和数据类型
单引号和双引号
在PostgreSQL中,写SQL语句时:
- 单引号用来标识实际的值;
- 双引号用来标识一个关键字,比如表名,字段名。
1 | -- 单引号写具体的值,双引号类似MySQL的``标记,用来填充关键字 |
数据类型转换
第一种方式:只需要在值的前面,添加上具体的数据类型即可
1 | -- 将字符串转成位图类型 |
第二种方式:也可以在具体值的后面,添加上 ::类型,来指定
1 | -- 数据类型 |
第三种方式:使用CAST函数
1 | -- 类型转换的完整写法 |
布尔类型
布尔类型可以存储三个值,true,false,null
1 | -- 布尔类型的约束没有那么强,true,false大小写随意,他会给你转,同时yes,no这种他也认识,但是需要转换 |
boolean类型在做and和or的逻辑操作时的结果:
字段A | 字段B | a and b | a or b |
---|---|---|---|
true | true | true | true |
true | false | false | true |
true | NULL | NULL | true |
false | false | false | false |
false | NULL | false | NULL |
NULL | NULL | NULL | NULL |
数值类型
整型
整型比较简单,主要就是三个:
- smallint、int2:2字节
- integer、int、int4:4字节
- bigint、int8:8字节
使用策略如下:
- 正常就用integer;
- 如果要存主键,比如雪花算法,那就bigint;
- 要节约空间,就用smallint。
浮点型
浮点类型就关注两个(其实是一个)
- decimal(n,m):本质就是numeric,PostgreSQL会帮转换;
- numeric(n,m):PostgreSQL本质的浮点类型。
针对浮点类型的数据,使用numeric即可。
序列
MySQL中的主键自增,是基于auto_increment去实现,没有序列的对象。
PostgreSQL和Oracle十分相似,支持序列:sequence,没有auto_increment。
序列的正常构建方式:
1 | create sequence schema_oliver.table_id_seq; |
注意:
- 默认情况下,seqeunce的起始值是0,每次nextval递增1,最大值9223372036854775807;
- 告诉缓存,插入的数据比较多,可以指定告诉缓存,一次性计算出20个后续的值,nextval时,就不可以不去计算,直接去高速缓存拿值,效率会有一内内的提升;
- 序列大多数的应用,是用作表的主键自增效果。
1 | -- 表自增 |
上面这种写法没有问题,但是很麻烦。
PostgreSQL提供了序列的数据类型,可以在声明表结构时,直接指定序列的类型即可。
bigserial相当于是bigint类型设置了序列实现自增。
类型对应如下:
- smallserial对应smallint;
- serial对应int;
- bigserial对应bigint。
1 | -- 表自增 |
注意:
- 在drop表之后,序列不会被删除,但是序列会变为不可用的状态。 因为序列在使用serial去构建时,会绑定到指定表的指定列上。
- 如果是单独构建序列,再构建表,使用传统方式实现,序列和表就是相对独立的。
数值的常见操作
针对数值可以实现加减乘除取余这5个操作
还有其他的操作方式
操作符 | 描述 | 示例 | 结果 |
---|---|---|---|
^ | 幂 | 2 ^ 3 | 8 |
|/ | 平方根 | |/ 36 | 6 |
@ | 绝对值 | @ -5 | 5 |
& | 与 | 31 & 16 | 16 |
| | 或 | 31|32 | 63 |
<< | 左移 | 1<<1 | 2 |
>> | 右移 | 16>>1 | 8 |
数值操作也提供了一些函数,比如pi(),round(数值, 位数),floor(),ceil()
字符串类型
字符串类型用的是最多的一种,在PostgreSQL里,主要支持三种:
- character(就是MySQL的char类型),定长字符串。(最大可以存储1G)
- character varying(varchar),可变长度的字符串。(最大可以存储1G)
- text(跟MySQL一样)长度特别长的字符串。
注意: 字符串的拼接一要要使用||来拼接。
其他的函数,可以查看:http://www.postgres.cn/docs/12/functions-string.html
日期类型
在PostgreSQL中,核心的时间类型,就三个。
- timestamp(时间戳,年月日时分秒)
- date(年月日)
- time(时分秒)
在PostgreSQL中,声明时间的方式。
只需要使用字符串正常的编写 yyyy-MM-dd HH:mm:ss 就可以转换为时间类型。
直接在字符串位置使用之前讲到的数据类型转换就可以了。
当前系统时间:
- 可以使用now作为当前系统时间(没有时区的概念)
1
2
3select timestamp 'now';
-- 直接查询now,没有时区的概念
select time with time zone 'now' at time zone '08:00:00' - 也可以使用current_timestamp的方式获取(推荐,默认东八区)
日期类型的运算:
- 正常对date类型做+,-操作,默认单位是天
- date + time = timestamp~~~
1
select date '2011-11-11' + time '12:12:12' ;
- 可以针对timestamp使用interval的方式进行 +,- 操作,在查询以时间范围为条件的内容时,可以使用
1
select timestamp '2011-11-11 12:12:12' + interval '1day' + interval '1minute' + interval '1month';
枚举类型
枚举类型MySQL也支持,只是没使用,PostgreSQL同样支持这种数据类型
可以声明枚举类型作为表中的字段类型,这样可以无形的给表字段追加规范。
1 | -- 声明一个星期的枚举,值自然只有周一~周日。 |
IP类型
PostgreSQL支持IP类型的存储,支持IPv4,IPv6,甚至MAC地址类型也支持。
IP类型,可以在存储IP时,帮助做校验,其次也可以针对IP做范围查找。
IP校验:
IP范围查找:
JSON&JSONB类型
JSON在MySQL8.x中也做了支持,但是MySQL支持的不好,因为JSON类型做查询时,基本无法给JSON字段做索引。
PostgreSQL支持JSON类型以及JSONB类型,JSON和JSONB的使用基本没区别。
抛开JSON类型,本质上JSON格式就是一个字符串,比如MySQL5.7不支持JSON的情况的下,使用text也可以,但是字符串类型无法校验JSON的格式,单独的字符串也没有办法只获取JSON中某个key对应的value。
JSON和JSONB的区别:
- JSON类型无法构建索引,JSONB类型可以创建索引;
- JSON类型的数据中多余的空格会被存储下来,JSONB会自动取消多余的空格;
- JSON类型甚至可以存储重复的key,JSONB不会保留多余的重复key(只保留最后一个);
- JSON会保留存储时key的顺序,JSONB不会保留原有顺序。
JSON中key对应的value的数据类型
JSON | PostgreSQL |
---|---|
String | text |
number | numeric |
boolean | boolean |
null | (none) |
1 | [ |
操作JSON:
- 上述的四种JSON存储的类型:
1
2select '9'::JSON,'null'::JSON,'"oliver"'::JSON,'true'::json;
select '9'::JSONB,'null'::JSONB,'"oliver"'::JSONB,'true'::JSONB; - JSON数组
1
select '[9,true,null,"我是字符串"]'::JSON;
- JSON对象
1
2select '{"name": "张三","age": 23,"birthday": "2011-11-11","gender": null}'::json;
select '{"name": "张三","age": 23,"birthday": "2011-11-11","gender": null}'::jsonb; - 构建表存储JSON
1
2
3
4
5
6
7
8
9
10
11
12create table test(
id bigserial,
info json,
infob jsonb
);
insert into
test
(info,infob)
values
('{"name": "张三" ,"age": 23,"birthday": "2011-11-11","gender": null}',
'{"name": "张三" ,"age": 23,"birthday": "2011-11-11","gender": null}')
select * from test;
- 构建索引的效果
1
2create index json_index on test(info);
create index jsonb_index on test(infob);
JSON还支持很多函数,可以在文档中查询:http://www.postgres.cn/docs/12/functions-json.html
复合类型
复合类型就好像Java中的一个对象,Java中有一个User,User和表做了一个映射,User中有个人信息对象,基于符合类型映射个人信息。
1 | public class User { |
按照上面的情况,将Info构建成一个复合类型
1 | -- 构建复合类型,映射上Info |
数组类型
数组还是要依赖其他类型,比如在设置住址,住址可能有多个住址,可以采用数组类型去修饰字符串。
PostgreSQL中,指定数组的方式就是[],可以指定一维数组,也支持二维甚至更多维数组。
构建数组的方式:
1 | drop table test; |
其他特殊情况?
- 如果要存储字符串数组?
- 如果存储的数组中有双引号怎么办?
- 如果有大括号怎么办?
1 | -- 如果存储的数组中的值,有单引号怎么办? |
数组的比较方式
1 | -- 包含 |