PostgreSQL環境下,觸發器、索引和角色的建立
建立表觸發器的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;
注:
a.觸發器函式是觸發器觸發時呼叫,函式返回的型別必須是TRIGGER ,且不能有任何引數
b.postgresql觸發器函式中自帶一些特殊變數:
NEW:資料型別是record,在insert、update操作觸發時儲存新的資料行
OLD:資料型別是record,在update、delete操作觸發時儲存舊的資料行
TG_OP:內容為“INSERT”,“UPDATE”,“DELETE”,“TRUNCATE”,用於指定DML語句型別
TG_TABLE_NAME:觸發器所在表的表名稱 TG_SCHEMA_NAME:觸發器所在表的模式
建立觸發器
表觸發器
CREATE TRIGGER example_trigger AFTER INSERT OR UPDATE ON COMPANY
FOR EACH ROW EXECUTE PROCEDURE auditlogfunc()
意思 :在company表中插入或更新後建立觸發器example_trigger
對於每一行執行過程auditlogfunc();
檢視觸發器
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;
2.查詢索引
1、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)
2、 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