PostgreSQL 9.5新特性

PostgreSQL 9.5新特性

 

一、RLS行级安全策略详解

"Row-Level Security (RLS) support" 9.5版本的主要特性之一,提供了基于行的安全策略,限制数据库用户的查看表数据权限

eg.

1.创建测试表,插入测试数据

fdb=> create table test_row(id serial primary key, username text, log_event text, create_time timestamp(0) without time zone default clock_timestamp());

CREATE TABLE

 

fdb=> insert into test_row(username,log_event) values('user1','user1:aaa');

INSERT 0 1

fdb=> insert into test_row(username,log_event) values('user1','user1:aadsfdfa');

INSERT 0 1

fdb=> insert into test_row(username,log_event) values('user2','user2:aadsfdfa');

INSERT 0 1

fdb=> insert into test_row(username,log_event) values('user2','user2:test');

INSERT 0 1

fdb=> insert into test_row(username,log_event) values('user3','user3:test3');

INSERT 0 1

fdb=> insert into test_row(username,log_event) values('user3','user3:test3333');

INSERT 0 1

fdb=> insert into test_row(username,log_event) values('user4','user4:test3333');

INSERT 0 1

 

2.创建user1,user2,user3测试用户

[pg95@db1 ~]$ psql fdb

psql (9.5alpha1)

Type "help" for help.

 

fdb=# create role user1 with login;

CREATE ROLE

fdb=# create role user2 with login;

CREATE ROLE

fdb=# create role user3 with login;

CREATE ROLE

 

fdb=> grant select on test_row to user1,user2,user3;

GRANT

 

fdb=> grant usage on schema fdb to user1,user2,user3;

GRANT

 

3.user登录可以查询到全部数据

fdb=> \c fdb user1

You are now connected to database "fdb" as user "user1".

 

fdb=> select * from fdb.test_row;

id | username | log_event | create_time

----+----------+----------------+---------------------

1 | user1 | user1:aaa | 2015-07-30 14:48:49

2 | user1 | user1:aadsfdfa | 2015-07-30 14:48:54

3 | user2 | user2:aadsfdfa | 2015-07-30 14:48:59

4 | user2 | user2:test | 2015-07-30 14:49:06

5 | user3 | user3:test3 | 2015-07-30 14:49:15

6 | user3 | user3:test3333 | 2015-07-30 14:49:24

7 | user4 | user4:test3333 | 2015-07-30 14:49:29

(7 rows)

 

4.给表添加policy

[pg95@db1 ~]$ psql fdb fdb

psql (9.5alpha1)

Type "help" for help.

 

fdb=> CREATE POLICY policy_test_row ON test_row

fdb-> FOR SELECT

fdb-> TO PUBLIC

fdb-> USING (username = current_user);

CREATE POLICY

 

fdb=> select relname,relrowsecurity from pg_class where relname='test_row';

relname | relrowsecurity

----------+----------------

test_row | f

(1 row)

 

fdb=> ALTER TABLE test_row ENABLE ROW LEVEL SECURITY;

ALTER TABLE

 

fdb=> select relname,relrowsecurity from pg_class where relname='test_row';

relname | relrowsecurity

----------+----------------

test_row | t

(1 row)

备注:给表 test_row 添加 policy ,限制数据库登陆用户仅允许查看当前用户的日志记录。

 

5.测试

user1用户登录

fdb=> \c fdb user1

You are now connected to database "fdb" as user "user1".

 

fdb=> select * from fdb.test_row;

id | username | log_event | create_time

----+----------+----------------+---------------------

1 | user1 | user1:aaa | 2015-07-30 14:48:49

2 | user1 | user1:aadsfdfa | 2015-07-30 14:48:54

(2 rows)

user2用户登录

fdb=> \c fdb user2

You are now connected to database "fdb" as user "user2".

 

fdb=> select * from fdb.test_row;

id | username | log_event | create_time

----+----------+----------------+---------------------

3 | user2 | user2:aadsfdfa | 2015-07-30 14:48:59

4 | user2 | user2:test | 2015-07-30 14:49:06

(2 rows)

备注:user1 用户仅能查看 username 值为'user1' 的记录,user2用户仅能查看 username值为 'user2'的记录。

实验结果:对应的用户只能查看对应的行记录,限制数据库用户的查看表数据权限

 

二、UPSERT

INSERT ... ON CONFLICT, also known as UPSERT

eg1.

[postgres@cqs ~]$ psql

psql (9.5alpha2)

Type "help" for help.

postgres=# \c mydb

mydb=# create table ins_update_test(id integer primary key,name text);

CREATE TABLE

mydb=#

mydb=# insert into ins_update_test values(100,'bingbang');

INSERT 0 1

mydb=# select * from ins_update_test;

 id  |   name   

-----+----------

 100 | bingbang

(1 row)

mydb=# insert into ins_update_test values(100,'xiaobang');

ERROR:  duplicate key value violates unique constraint "ins_update_test_pkey"

DETAIL:  Key (id)=(100) already exists.

这时候如果想插入更新ins_update_test表的数据时,可以采用以下方法

mydb=# insert into ins_update_test values(100,'xiaobang') on conflict(id) do update set name=excluded.name;

INSERT 0 1

mydb=#

mydb=#select * from ins_update_test;

 id  |   name   

-----+----------

 100 | xiaobang

(1 row)

mydb=#

解决方案:结尾要加上 on on conflict(id) do update set name=excluded.name;

原因是id是主键,具有唯一性,所以也就是更新数据库表的其他字段name

eg2.

Block-Range Indexes (BRIN)

BRIN(Block Range Index):保存数据块的值的摘要信息,如存储某一组块里面所有记录中的最大最小值,与Exadata Storage Index 相似。 通过BRIN 我们可以让Index 大小指数级缩小,当然不恰当的使用也会影响性能

mydb=# create table ins_update_test2(x integer primary key,status text);

CREATE TABLE

mydb=# insert into ins_update_test2 values(1,'old'),(3,'old'),(5,'old');

INSERT 0 3

mydb=#

mydb=# select * from ins_update_test2;

 x | status

---+--------

 1 | old

 3 | old

 5 | old

(3 rows)

mydb=# insert into ins_update_test2 select  *,'new' from generate_series(2,5) on conflict(x) do update set status='conflict';

INSERT 0 4

mydb=#

mydb=# select * from ins_update_test2;

 x |  status  

---+----------

 1 | old

 2 | new

 3 | conflict

 4 | new

 5 | conflict

(5 rows)

 

三、jsonb的相关操作

 

jsonb || jsonb (concatenate / overwrite)

The || operator allows us to combine 2 jsonb objects. If there's overlap, values are replaced on the highest level.

译:||运算符允许我们将两个jsonb对象连接起来,如果有重叠的键,值会被后者替换。

eg1.没有重复键的

mydb=# select '{"name":"cqs","age":"24"}'::jsonb || '{"town":"China"}'::jsonb;

                   ?column?                    

-----------------------------------------------

 {"age": "24", "name": "cqs", "town": "China"}

(1 row)

eg2.有重复键的

mydb=# select '{"name":"cqs","age":"24","town":"China"}'::jsonb || '{"town":"English"}'::jsonb;

                    ?column?                     

-------------------------------------------------

 {"age": "24", "name": "cqs", "town": "English"}

(1 row)

eg3.有重复键

mydb=# select '{"name":"cqs","age":"24","town":"China","friends":{"name":"ysg","age":"24"}}'::jsonb || '{"friends":{"name":"xrl"}}'::jsonb;

 

                                 ?column?                                  

---------------------------------------------------------------------------

 {"age": "24", "name": "cqs", "town": "China", "friends": {"name": "xrl"}}

(1 row)

 

jsonb - text / int (remove key / array element)

译:删除jsonb的键或数组的值

eg1.删除jsonb的键

mydb=# select '{"name":"cqs","age":"24"}'::jsonb - 'age';

    ?column?     

-----------------

 {"name": "cqs"}

(1 row)

eg2.删除数组的键值

mydb=# select '["red","green","blue"]'::jsonb - 1;

    ?column?     

-----------------

 ["red", "blue"]

(1 row)

 

jsonb #- text[] / int (remove key / array element in path)

译:删除指定路径的键值

eg1.jsonb

mydb=# select '{"name":"cqs","age":"24","town":"China","friends":{"name":"ysg","age":"24"}}'::jsonb #- '{friends,age}'::text[];              

                                 ?column?                                  

---------------------------------------------------------------------------

 {"age": "24", "name": "cqs", "town": "China", "friends": {"name": "ysg"}}

(1 row)

eg2.array

mydb=# select '{"name":"cqs","age":"24","town":"China","friends":["ysg","wjr","czm","wy"]}'::jsonb #- '{friends,1}'::text[];         

                                    ?column?                                    

--------------------------------------------------------------------------------

 {"age": "24", "name": "cqs", "town": "China", "friends": ["ysg", "czm", "wy"]}

(1 row)

 

jsonb_set() --function

构造:jsonb_set(target jsonb,path text[],new_value jsonb,create_missing boolean)

语法:

jsonb_set(

  target jsonb,   # The jsonb value you're amending.

  path text[],   # The path to the value you wish to add to or change, represented as a text array.   

  new_value jsonb,   # The new object, key : value pair or array value(s) to add to or change.  

  create_missing boolean   # An optional field that, if true (default), creates the value if the key doesn't already exist.

         # If false, the path must exist for the update to happen, or the value won't be updated.

  )

eg1.修改对应的键值(create_missing默为true

mydb=# select jsonb_set('{"name":"cqs","contact":{"phone":"xxxxxxxxxxxx","qq":"xxxxxxxxxxxx"}}'::jsonb,'{contact,qq}','"1254325782"'::jsonb);

                                jsonb_set                                 

--------------------------------------------------------------------------

 {"name": "cqs", "contact": {"qq": "xxxxxxxxxxxx", "phone": "xxxxxxxxxxxx"}}

(1 row)

eg2.新增键值

mydb=# select jsonb_set('{"name":"cqs","contact":{"phone":"xxxxxxxxxxxx ","qq":"xxxxxxxxxxxx"}}'::jsonb,'{contact,email}','"xxxxxxxxxxxx@qq.com"'::jsonb);

                                               jsonb_set                                       

-----------------------------------------------------------------------------------------------

 {"name": "cqs", "contact": {"qq": "xxxxxxxxxxxx", "email": "xxxxxxxxxxxx@qq.com", "phone": "xxxxxxxxxxxx"}}

(1 row)

eg.新增键值时设置create_missing参数为false

mydb=# select jsonb_set('{"name":"cqs","contact":{"phone":"xxxxxxxxxxxx","qq":"xxxxxxxxxxxx"}}'::jsonb,'{contact,email}','"xxxxxxxxxxxx@qq.com"'::jsonb,false);

                                jsonb_set                                

-------------------------------------------------------------------------

 {"name": "cqs", "contact": {"qq": "xxxxxxxxxxxx", "phone": "xxxxxxxxxxxx"}}

(1 row)

eg3.数组中的处理(修改contact数组中第2个键的值)

mydb=# select jsonb_set('{"name":"cqs","contact":["xxxxxxxxxxxx","8061492521","xxxxxxxxxxxx"]}'::jsonb,'{contact,1}','"xxxxxxxxxxxx"'::jsonb);           

                                jsonb_set                                 

--------------------------------------------------------------------------

 {"name": "cqs", "contact": ["xxxxxxxxxxxx", "8061492521", "xxxxxxxxxxxx"]}

(1 row)

 

jsonb_pretty() --function

作用:格式化

eg.

mydb=# select jsonb_pretty(jsonb_set('{"name":"cqs","contact":{"phone":"xxxxxxxxxxxx","qq":"xxxxxxxxxxxx"}}'::jsonb,'{contact,email}','"xxxxxxxxxxxx@qq.com"'::jsonb,true));

             jsonb_pretty              

---------------------------------------

 {                                    +

     "name": "cqs",                   +

     "contact": {                     +

         "qq": "xxxxxxxxxxxx",           +

         "email": "xxxxxxxxxxxx@qq.com",+

         "phone": "xxxxxxxxxxxx"       +

     }                                +

 }

(1 row)

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值