PostgreSQL環境下,觸發器、索引和角色的建立

建立表觸發器的SQL語句sql

CREATE TRIGGER example_trigger BEFORE INSERT ON teaches

FOR EACH ROW

EXECUTE PROCEDURE example_function();

 

實例 :數據庫

首先建立測試表、視圖函數

CREATE TABLE COMPANY(  
       ID INT PRIMARY KEY NOT NULL,  
       NAME TEXT NOT NULL,  
       AGE INT NOT NULL,  
       ADDRESS CHAR(50),  
       SALARY REAL  
    );
 
   CREATE TABLE AUDIT_HIS(  
       EMP_ID INT NOT NULL,
       EMP_NAME TEXT NOT NULL,  
       ENTRY_DATE TEXT NOT NULL  
   );
 
   CREATE TABLE AUDIT(  
       EMP_ID INT NOT NULL,
       EMP_NAME TEXT NOT NULL,  
       ENTRY_DATE TEXT NOT NULL  
   );
 
   CREATE OR REPLACE VIEW "public"."company_view" AS 
   SELECT company.id,company.name,company.age

 2.建立觸發器函數

CREATE OR REPLACE FUNCTION auditlogfunc() RETURNS TRIGGER AS $$  
        BEGIN  
            INSERT INTO AUDIT_HIS(EMP_ID,EMP_NAME,ENTRY_DATE) VALUES (OLD.ID,OLD.NAME,current_timestamp); 
            INSERT INTO AUDIT(EMP_ID,EMP_NAME,ENTRY_DATE) VALUES (NEW.ID,NEW.NAME,current_timestamp);   
        RETURN NULL;   
        END;  
    $$ LANGUAGE plpgsql;

注:post

a.觸發器函數是觸發器觸發時調用函數返回的類型必須是TRIGGER ,且不能有任何參數測試

b.postgresql觸發器函數中自帶一些特殊變量:spa

NEW:數據類型是record,在insert、update操做觸發時存儲新的數據行
OLD:數據類型是record,在update、delete操做觸發時存儲舊的數據行
TG_OP:內容爲「INSERT」,「UPDATE」,「DELETE」,「TRUNCATE」,用於指定DML語句類型
TG_TABLE_NAME:觸發器所在表的表名稱 TG_SCHEMA_NAME:觸發器所在表的模式 
 .net

建立觸發器

表觸發器postgresql

CREATE TRIGGER example_trigger AFTER INSERT OR UPDATE ON COMPANY  
    FOR EACH ROW EXECUTE PROCEDURE auditlogfunc()

意思 :在company表中插入或更新後建立觸發器example_triggercode

對於每一行執行過程auditlogfunc();blog

 

視圖觸發器

CREATE TRIGGER company_view_trigger AFTER UPDATE ON company_view 
    EXECUTE PROCEDURE auditlogfunc();

刪除觸發器

刪除company表中的example_trigger觸發器

DROP TRIGGER example_trigger on COMPANY;

刪除函數

drop function function_name (parameters_list);

查看全部觸發器

SELECT * FROM pg_trigger;

測試

INSERT INTO COMPANY VALUES(1, '小米科技', 8, '北京市朝陽區', 9999);
UPDATE COMPANY SET NAME ='阿里巴巴' WHERE ID ='1';

實例 :

1.建表

CREATE TABLE student (
  id   int primary key,
  name varchar(50)
);
 
CREATE TABLE score (
  studentId  int,
   math     int 
);
2.插入數據

INSERT INTO student VALUES(1,'April');
INSERT INTO student VALUES(2,'Harris');
 
INSERT INTO score VALUES(1, 98);
INSERT INTO score VALUES(2,77);
3.建立執行函數

   爲觸發器建立一個執行函數,函數的返回類型是觸發器類型。

CREATE OR REPLACE FUNCTION student_delete_trigger()
RETURNS TRIGGER AS $$
BEGIN
   DELETE FROM score where studentId = OLD.id;
    RETURN OLD;
END;
$$
LANGUAGE plpgsql;

 

查看建立的觸發器

postgres=# SELECT * FROM pg_trigger;


3.建立觸發器

CREATE TRIGGER delete_trigger 
    AFTER DELETE ON student
    FOR EACH ROW EXECUTE PROCEDURE student_delete_trigger();
4.刪除數據

    如今,爲了驗證觸發器正常工做,刪除學生表中id爲2的學生信息,而後查看其成績信息是否也被刪除了?

DELETE FROM student where id = 2;
select * from student;
select * from score;
    執行結果:

           表student                                                                  圖:表score

    結論:當刪除學生表中的一條記錄時,經過觸發器,把其在成績表中的記錄也刪除了。

 

 

 

PostgreSql INDEX 索引總結

1.建立索引
create index index_name on table_name(field_name1, field_name2,······);

 

create index index_name on table_name using btree 

create index idx_t_hash_1 on t_hash using btree (info); 建立索引 idx_t_hash_1,在t_hash表中的info列中。

 

create index  tbl_bb_index  on  tbl_bb(id,name);

注:tbl_bb  位表名稱,  tbl_bb_index  爲建立的索引名稱,  id 和 name 爲 表裏的字段

注:默認建立B-tree索引,-- 使用b-tree索引會報錯,由於長度超過了1/3的索引頁大小。

使得添加的index 生效:

ANALYSE index_name;

注意 :索引種類:btree、hash、 gist、spgist、 gin以及brin。 默認方法是btree。

給tmp表添加idx_tmp,索引方法是hash(不是默認的btree

postgres=# create index idx_tmp on tmp using hash(c0);

注意事項,官網特別強調:

Hash索引操做目前不被WAL記錄,所以存在未寫入修改,在數據庫崩潰後須要用REINDEX命令重建Hash索引。

 

使用單列索引

在name列創建索引

CREATE INDEX index_name_100000 ON test_100000 (name);

使用覆蓋索引

#CREATE INDEX index_name_id_password_description_100000 ON test_1000000(name, id, password, description);

使用hash索引,在name列創建索引

CREATE INDEX hash_name_1000000 ON test_1000000 USING hash (name);

統計索引和表相關信息

SELECT * FROM pg_stat_user_indexes;  

SELECT * FROM pg_stat_user_tables;

查看某個索引大小

SELECT pg_size_pretty(pg_relation_size(indexrelname)); 

SELECT pg_size_pretty(pg_relation_size('idx_ka_name'));

 

 

2.查詢索引
    一、select * from pg_indexes where tablename ='table_name';

runoobdb=#  select * from pg_indexes where tablename ='company';           #查詢company表的索引
                                                          RUNOOBDB
 schemaname | tablename |     indexname     | tablespace |                     
        indexdef                              
------------+-----------+-------------------+------------+---------------------
----------------------------------------------
 public     | company   | company_pkey      |            | CREATE UNIQUE INDEX 
company_pkey ON company USING btree (id)
 public     | company   | unique_table_a_id |            | CREATE UNIQUE INDEX 
unique_table_a_id ON company USING btree (id)
(2 rows)

    二、   select * from pg_statio_all_indexes where relname='tbname';

runoobdb=# select * from pg_statio_all_indexes where relname='company';
                                           RUNOOBDB
 relid | indexrelid | schemaname | relname |   indexrelname    | idx_blks_read 
| idx_blks_hit 
-------+------------+------------+---------+-------------------+---------------
+--------------
 16487 |      16493 | public     | company | company_pkey      |             1 
|            1
 16487 |      16518 | public     | company | unique_table_a_id |             1 
|            1
(2 rows)

 

3.刪除索引
drop index index_name;

index_name是要刪除的索引名

注意 : 沒法刪除DBMS爲主鍵約束和惟一約束自動建立的索引

 

 

 

常見無需建立索引狀況
a. 頻繁更新的字段不適合建立索引,由於每次更新不僅僅是更新記錄,還會更新索引,保存索引文件;

b.表記錄太少,不須要建立索引;

c.常常增刪改的表,不須要建立索引;

d.表中包含大量重複數據,不須要建立索引,例如性別字段,只有男女,不適合創建索引; 

常見索引無效狀況
a. 沒有查詢條件,或者查詢條件沒有創建索引;

b. 在查詢條件上沒有使用引導列;

c. 查詢的數量是大表的大部分,應該是30%以上;

d. 使用內部函數致使索引失效,例:select * from test where round(id)=10;

e. 表記錄較少

f. 隱式轉換致使索引失效,例如:表的字段tu_mdn定義爲varchar2(20), 但在查詢時把該字段做爲number類型以where條件傳給數據庫:

錯誤的例子:select * from test where tu_mdn=13333333333; 

正確的例子:select * from test where tu_mdn='13333333333'; 

g. 索引列進行運算致使索引失效,運算包括(+,-,*,/,! 等),例:

select * from test where round(id)=10; 

runoobdb=#  select * from company where round(id)=10; 
              RUNOOBDB
 id | name | age | address | salary 
----+------+-----+---------+--------
(0 rows)

h. like "%_" 百分號在前;

i.單獨引用複合索引裏非第一位置的索引列;

j. B-tree索引 is null不會走,is not null會走,位圖索引 is null,is not null 都會走  
 

建立角色

在建立用戶時賦予角色屬性

postgres=# CREATE  ROLE test_user_3 CREATEDB;                /*具備建立數據庫的屬性*/  

postgres=# CREATE ROLE test_user_4 CREATEDB PASSWORD '123456';            /*具備建立數據庫及帶有密碼登錄的屬性 */  

 

CREATE ROLE david;  //默認不帶LOGIN屬性

CREATE USER sandy;  //默認具備LOGIN屬性

鏈接數據庫

psql –h IP  -U david;    //不能登陸

psql –h IP  -U sandy;   //能登陸

修改david 的權限,增長LOGIN權限
 ALTER ROLE david LOGIN ;

ALTER ROLE davidwith password 'david';

ALTER ROLE sandywith password 'sandy';

再次驗證LOGIN屬性
 psql -h 127.0.0.1 -U sandy -d postgres

查看系統表 select * from pg_roles;

 

建立角色renee 並賦予其建立數據庫及帶有密碼登陸的屬性。 
postgres=# CREATE ROLE renee CREATEDB PASSWORD 'abc123' LOGIN;

 

 建立角色bella 並賦予其CREATEDB 的權限。

CREATE ROLE bella CREATEDB ;

查看如今的角色屬性

ALTER ROLE bella WITH LOGIN;

賦予renee 建立角色的權限
postgres=# ALTER ROLE renee WITH CREATEROLE;

賦予david 帶密碼登陸權限
postgres=# ALTER ROLE david WITH PASSWORD 'ufo456';

設置sandy 角色的有效期
postgres=# ALTER ROLE sandy VALID UNTIL '2014-04-24';

postgres=# SELECT * from pg_roles ;

 

連接 :

 

PostgreSQL的用戶、角色和權限管理:https://blog.csdn.net/eagle89/article/details/80363365

PostgreSql INDEX 索引總結 :https://blog.csdn.net/nioqnw/article/details/84750297

PostgreSql TRIGGER 觸發器簡單樣例 :https://blog.csdn.net/nioqnw/article/details/84633181

PostgreSQL觸發器(一)建立觸發器 :https://blog.csdn.net/liyazhen2011/article/details/82800446

postgresql 索引之 hash :https://blog.csdn.net/ctypyb2002/article/details/83273742

相關文章
相關標籤/搜索