1. 数字类型
1.1 数字类型:
| 类型名称 | 存储长度 | 描述 | 范围 |
|---|---|---|---|
| smallint(int2) | 2字节 | 小范围整数类型 | -32 768到+32 767 |
| integer(int4) | 4字节 | 整数类型 | -2 147 483 648到+2 147 483 647 |
| bigint(int8) | 8字节 | 大范围整数类型 | -9 223 372 036 854 775 808到+9 223 372 036 854 775 807 |
| decimal | 可变 | 用户指定精度 | 小数点前131 072位;小数点后16 383位 |
| numeric | 可变 | 用户指定精度 | 小数点前131 072位;小数点后16 383位 |
| real | 4字节 | 变长,不精确 | 6位十进制精度 |
| double precision | 8字节 | 变长,不精确 | 15位十进制精度 |
| smallserial | 2字节 | smallint自增序列 | 1到32 767 |
| serial | 4字节 | integer自增序列 | 1到2 147 483 647 |
| bigserial | 8字节 | bigint自增序列 | 1到9 223 372 036 854 775 807 |
1.2 数字类型说明:
1. smallint、integer、bigint类型详细说明:smallint、integer、bigint都是整数类型,例如定义integer类型的表:create table test_integer (id1 integer,id2 int4);2. decimal和numeric类型详细说明:decimal和numeric是等效的,可以存储指定精度的多位数据比如带小数位的数据,适用于要求计算准确的数值运算。例如numeric(2,1) 即这个数不超过2位数,且小数点后面最多有一位,多出来的小数会被四舍五入。create table test (num numeric(2,1));insert into test values (2.2);num-----2.2insert into test values (2.26);num-----2.33. real和double precision是浮点数据类型numeric 可以存储最多1000位精度的数字并且准确地进行计算。非常适合用于货币金额和其它要求计算准确的数量。不过,numeric类型上的算术运算比整数类型或者浮点数类型要慢的多。4. smallserial、serial和bigserial类型是自增serial类型,如下创建一张测试表:postgres=# create table test_serial (id serial,flag text);CREATE TABLEpostgres=# insert into test_serial (flag) values ('a');INSERT 0 1postgres=# insert into test_serial (flag) values ('b');INSERT 0 1postgres=# insert into test_serial (flag) values ('c');INSERT 0 1postgres=# select * from test_serial;id | flag----+------1 | a2 | b3 | c(3 rows)
< http://www.javashuo.com/article/p-zwuoxwat-cq.html>
1.3 数字类型操作符和数学函数
1. 例如计算加、减、乘、除、模取余:postgres=# select 1+2,2*3,4/2,8%3;?column? | ?column? | ?column? | ?column?----------+----------+----------+----------3 | 6 | 2 | 22. 按模取余:postgres=# select mod(8,3);mod-----23. 四舍五入:postgres=# select round(10.2),round(10.9);round | round-------+-------10 | 114. 返回大于或等于给出参数的最小整数:postgres=# select ceil(3.6),ceil(-3.6);ceil | ceil------+------4 | -3(1 row)5. 返回小于或等于给出参数的最大整数:postgres=# select floor(3.6),floor(-3.6);floor | floor-------+-------3 | -4(1 row)
2.字符类型
2.1 字符类型:
| 字符类型名称 | 描述 |
|---|---|
| character varying(n),varchar(n) | 变长,字符最大数有限制 |
| character(n),char(n) | 定长,字符数没达到最大值则使用空白填充 |
| text | 变长,无长度限制 |
2.2 字符类型说明
1. 创建一张测试表,并插入一条测试数据:create table test_char(col1 varchar(4),col2 character(4));insert into test_char(col1,col2) values('a','a');2. 查看两个字段值的字符串长度:postgres=# select char_length(col1),char_length(col2) from test_char;char_length | char_length-------------+-------------1 | 13. 查看两个字段实际占用的物理空间大小:postgres=# select octet_length(col1),octet_length(col2) from test_char;octet_length | octet_length--------------+--------------1 | 4(1 row)
2.3 字符类型函数
① 计算字符串占用的字符数:postgres=# select char_length('abcd');char_length-------------4② 计算字符串占用的字节数:postgres=# select octet_length('abcd');octet_length--------------4③ 指定字符在字符串的位置:postgres=# select position('a' in 'abcd');position----------1④ 提取字符串中的子串:postgres=# select substring('abcdedfdfdd' from 4 for 4);substring-----------dedf⑤ 拆分字符串,split_part函数:# 以@为分隔符,提取第二列:postgres=# select split_part('abc@def@ghr','@',2);split_part------------def
3.时间/日期类型
3.1 时间类型:
| 字符类型名称 | 存储长度 | 描述 |
|---|---|---|
| timestamp[ (p) ] [without time zone] | 8字节 | 包括日期和时间,不带时区,简写timestamp |
| timestamp[ (p) ] with time zone | 8字节 | 包括日期和时间,带时区,简写成timestamptz |
| date | 4字节 | 日期,但不包含一天中的时间 |
| time[ (p) ] [without time zone] | 8字节 | 一天中的时间,不包含日期,不带时区 |
| time[ (p) ] [with time zone] | 12字节 | 一天中的时间,不包含日期,带时区 |
| interval[ fields ] [ (p) ] | 16字节 | 时间间隔 |
3.1.1 时间类型转换
① 系统自带的now()函数,默认返回的类型为timestamp [ (p) ] with time zone类型,如下所示:postgres=# select now();now-------------------------------2022-02-21 12:55:44.192936+08② 将timestimep[ (p) ] with time zone类型转换为timestimep without time zone类型:postgres=# select now()::timestamp without time zone;now----------------------------2022-02-22 12:30:30.851688③ 转换成date类型:postgres=# select now()::date;now------------2022-02-22④ 转换成time without time zone类型:postgres=# select now()::time without time zone;now-----------------12:31:44.490888⑤ 转换成time with time zone类型:postgres=# select now()::time with time zone;now--------------------12:32:12.679392+08
3.2 时间/日期类型操作符
① 日期相加:postgres=# select date '2017-07-29' + interval'1 days';?column?---------------------2017-07-30 00:00:00② 日期相减:postgres=# select date '2017-07-29' - interval'1 days';?column?---------------------2017-07-28 00:00:00③ 日期相乘:(例如100秒乘1秒)postgres=# select 100* interval '1 second';?column?----------00:01:40④ 日期相除:(例如将1小时除3)postgres=# select interval '1 hour' / double precision '3';?column?----------00:20:00
3.3 时间、日期类型常用函数:
① 显示当前时间:postgres=# select current_date,current_time;current_date | current_time--------------+--------------------2021-06-02 | 19:14:25.254973+08② extract函数,可以从日期、时间、数据类型中抽取年、月、日、时、分、秒信息:# 语法:extract (field from source)# field值可以为century、year、month、day、hour、minute、second等,source类型为timestamp、time、interval的值表达式,例如取年份,代码如下:postgres=# select extract(year from now());date_part-----------2021③ 对于timestamp类型,取月份和月份里的第几天:postgres=# select extract(month from now()),extract(day from now());date_part | date_part-----------+-----------6 | 2④ 取小时,分钟:postgres=# select extract(hour from now()),extract(minute from now());date_part | date_part-----------+-----------19 | 31⑤ 取秒:postgres=# select extract(second from now());date_part-----------25.230762⑥ 取当前日期所在年份中的第几周:postgres=# select extract(week from now());date_part-----------22⑦ 当天属于当前年份的第几天:postgres=# select extract(doy from now());date_part-----------153
4.布尔类型
4.1 布尔类型:
| 字符类型名称 | 存储长度 | 描述 |
|---|---|---|
| boolean | 1字节 | 状态为true或false |
4.2 布尔类型说明:
① true状态的有效值可以是TRUE、t、true、y、yes、on、1;false状态的有效值为FALSE、f、fase、n、no、off、0:# 创建表并插入数据:create table test_boolean(cola boolean,colb boolean);insert into test_boolean (cola,colb) values ('true','false');insert into test_boolean (cola,colb) values ('t','f')insert into test_boolean (cola,colb) values ('TRUE','FALSE');insert into test_boolean (cola,colb) values ('yes','no');insert into test_boolean (cola,colb) values ('y','n');insert into test_boolean (cola,colb) values ('1','0');insert into test_boolean (cola,colb) values (null,null);# 以上插入的是TRUE、t、true、y、yes、on、1和FALSE、f、fase、n、no、off、0,但最终显示结果都会以t或f进行显示,而插入的null值,则为空:

删除库下所有表:
DO $$ DECLARE r RECORD; BEGIN — if the schema you operate on is not”current”, you will want to — replace current_schema() in query with ‘schematodeletetablesfrom’ — and update the generate ‘DROP…’ accordingly. FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP EXECUTE ‘DROP TABLE IF EXISTS ‘ || quote_ident(r.tablename) || ‘ CASCADE’; END LOOP; END $$;
5.网络地址类型
5.1 网络地址类型:
| 字符类型名称 | 存储长度 | 描述 |
|---|---|---|
| cidr | 7或19字节 | IPv4和IPv6网络 |
| inet | 7或19字节 | IPv4和IPv6网络 |
| macaddr | 6字节 | MAC地址 |
| macaddr8 | 8字节 | MAC地址(EUI-64格式) |
5.2 网络地址演示说明:
① 说明:inet和cidr类型存储的网络地址格式为address/y,其中address表示IPv4或IPv6网络地址,y表示网络掩码位数,如果y省略,IPv4掩码为32,IPv6掩码为128。inet和cidr类型都会对数据合法性进行检查,如果数据不合法则报错:

② inet和cidr类型的差别:
cidr类型的输出默认带子网掩码,而inet不一定:

cidr类型对IP地址和子网掩码合法性进行检查而inet不会:

5.3 网络地址操作符:
| 操作符 | 描述 | 举例说明 |
|---|---|---|
| < | 小于 | inet’192.168.1.5’ < inet ‘192.168.1.6’ |
| <= | 小于等于 | inet ‘192.168.1.5’ <= inet ‘192.168.1.5’ |
| = | 等于 | inet’192.168.1.5’ = inet’192.168.1.5’ |
| >= | 大于等于 | inet ‘192.168.1.5’ >= inet ‘192.168.1.5’ |
| > | 大于 | inet’192.168.1.6’ > inet’192.168.1.5’ |
| <> | 不等于 | inet’192.168.1.5’ <> inet’192.168.1.6’ |
| << | 被包含 | inet’192.168.5’ << inet’192.168.1’/24 |
| <<= | 被包含或等于 | inet’192.168.1’ <<= inet’192.168.1’ |
| >> | 包含 | inet’192.168.1’/24 >> inet’192.168.5’ |
| >>= | 包含或等于 | inet’192.168.1’ >>= inet’192.168.1’ |
| && | 包含或被包含 | inet’192.168.1’/24 && inet’192.168.1.80/28’ |
| ~ | 按位取反 | ~inet’192.168.1.6’; |
| & | 按位与 | inet’192.168.1.6’ & inet’0.0.0.255’ |
| | | 按位或 | inet’192.168.1.6’ | inet’0.0.0.255’ |
| + | 加 | inet’192.168.1.6’ + 1 |
| - | 减 | inet’192.168.1.6’ – 1 |
| - | 减 | inet’192.168.1.6’ - inet’192.168.1.5’ |
5.4 网络地址操作符
① 取IP地址,返回文本格式:select host(cidr '192.168.1.0/24');② 取IP地址和网络掩码,返回文本格式:select text(cidr '192.168.1.0/24');③ 取网络地址子网掩码,返回文本格式:select netmask(cidr '192.168.1.0/24');



6.范围类型
6.1 范围类型:
| int4range | integer范围类型 |
|---|---|
| int8range | bigint范围类型 |
| numrange | numeric范围类型 |
| tsrange | timestamp范围类型 |
| tstzrange | timestamp范围类型 |
| daterange | date范围类型 |
6.2 范围类型说明:
① 用户可以通过create type自定义范围类型,integer范围类型举例:② daet范围类型举例:
6.3 范围类型操作符:
① 以下所包含的是否都大于3,如果是则显示f:② 以下所包含,左边的是否大于右边的,如果不是则显示f:③ 等于操作符:④ 计算交叉:⑤ 范围是否为空:⑥ 提取上边界:⑦ 提取下边界:







6.4 给范围类型创建索引:
① 范围类型数据支持创建GIST索引,GIST索引支持的操作符有“=” “&&” “<@” “@>” “<<” “-|-” “&>” “&<”等:create index idx_ip_address_range on ip_address using gist (ip_range);
6.5 演示说明:
① 创建一个json类型的表,并插入数据:create table test_json1 (id serial primary key,name json);insert into test_json1 (name) values ('{"col1":1,"col2":"francs","col3":"male"}');insert into test_json1 (name) values ('{"col1":2,"col2":"fp","col3":"male"}');② 查看表test_json1中的数据:③ 查看json数据的键值:select name -> 'col2' from test_json1 where id=1;④ 以文本的形式显示json数据的键值:select name ->> 'col2' from test_json1 where id = 1;


7.jsonb/json类型
7.1 jsonb/json差异
① jsonb的输入和输出键值的顺序不一样,而json则完全一样:select '{"bar":"baz","balance":7.77,"active":false}'::jsonb;select '{"bar":"baz","balance":7.77,"active":false}'::json;② jsonb类型会去掉数据中键值的空格:select '{"id":1, "name":"francs"}'::jsonb;③ jsonb会删除重复的键:select '{"id":1,"name":"francs","name":"test"}'::jsonb;




7.2 jsonb/json操作符
① 以文本格式显示json类型的字段键值可以使用“->>”操作符:select name ->> 'col2' from test_json1 where id=1;② 字符串是否作为顶层键值:select '{"a":1,"b":2}'::jsonb ? 'a';③ 删除json数据的键值:select '{"a":1,"b":2}'::jsonb - 'a';



7.3 jsonb/json函数
① 扩展最外层的json对象成为一组键/值结果集:select * from json_each('{"a":"foo","b":"bar"}');② 以文本形式返回结果:select * from json_each_text('{"a":"foo","b":"bar"}');③ row_to_json()函数,例如将一个普通表转换为json格式:create table test_copy (id serial not null,name varchar(30));insert into test_copy (name) values ('foo');select row_to_json(test_copy) from test_copy;④ 返回最外层的json对象中的键的集合:select * from json_object_keys('{"a":"foo","b":"bar"}');




7.4 jsonb键/值的追加、删除、更新:
① jsonb键/值追加可通过“||”操作符,例如增减sex键:select '{"name":"francs","age":"31"}'::jsonb || '{"sex":"male"}'::jsonb;② 删除键/值:# 方法一,通过“-”删除:select '{"name":"james","emai1":"james@localhost"}'::jsonb - 'emai1';select '["red","green","blue"]'::jsonb -0;# 方法二,通过“#-”删除指定键/值,通常用于有嵌套json数据删除场景:# 如删除嵌套contact中的fax值:select '{"name":"James","contact":{"phone":"01234 567890","fax":"01987 543210"}}'::jsonb #- '{contact,fax}'::text[];# 删除嵌套aliases中的位置为1的键/值:select '{"name":"James","aliases":["Jamie","The Jamester","J Man"]}'::jsonb #- '{aliases,1}'::text[];③ 键/值更新:# 方法一,使用“||”操作符,如更改age列:select '{"name":"francs","age":"31"}'::jsonb || '{"age":"32"}'::jsonb;# 方法二,使用jsonb_set函数:# 如更新age列:select jsonb_set('{"name":"francs","age":"31"}'::jsonb,'{age}','"32"'::jsonb,false);# 如增加set列:select jsonb_set('{"name":"francs","age":"31"}'::jsonb,'{set}','"male"'::jsonb,true);








8.数据类型转换
8.1 通过CAST函数进行转换
① 将varchar字符类型转换成text类型:select cast(varchar'123' as text);② 将varchar字符类型转换成int4类型:select cast(varchar'123' as int4);
8.2 通过 :: 操作符经行转换
① 转换为int4和numeric类型:select 1::int4,3/2::numeric;② 通过SQL查询某个表的字段名称:# 方法一,在使用类型转换之前需要两步完成:# 首先获取指定表的OID:select oid,relname from pg_class where relname = 'test_json1';# 在通过OID查询某个表的字段:select attname from pg_attribute where attrelid='33036' and attnum > 0;# 方法二,使用类型转换后可一步完成:select attname,attrelid,attnum from pg_attribute where attrelid='test_json1'::regclass and attnum >0;




