1. 程式人生 > >資料庫中觸發器和索引的使用

資料庫中觸發器和索引的使用

觸發器

 什麼是觸發器?

   觸發器是一種過程,與表關係密切,用於保護表中的資料。當一個表被修改(insert、update或delete)時,觸發器字動執行。觸發器課實現多個表之間資料的一致性和完整性。

 觸發器的型別有3種:

   DML觸發器:Oracle可以在DML語句進行觸發,可以在DML操作前或操作後進行觸發,並且可以對每個行或語句操作上進行觸發。

   替代觸發器:由於在Oracle裡,不能直接對由兩個以上的表建立的檢視進行操作,所以給出了替代觸發器。它就是Oracle 8專門為進行檢視操作的一種處理方法。

   系統觸發器:Oracle從8i開始提供了第三種類型的觸發器叫系統觸發器。它可以在Oracle資料庫系統的事件中進行觸發,如Oracle系統的啟動與關閉等。

建立DML觸發器:

  DML觸發器由DML語句激發,並且由該語句的型別決定DML觸發器的型別

  可以定義DML觸發器進行insert、update、delete操作

  DML觸發器可以在上述操作之前或之後激發,也可以在行或語句操作上激發

觸發器的語法:

 

觸發器的基本使用應用例項:

-- 當有員工的工資發生變化時,觸發事件修改該員工對應的部門工資資料
create or replace trigger dept_sal_trigger
--觸發的時機
after 
--觸發的事件
update or insert or delete on emp1
--把員工對應的部門工資進行修改
declare
  cursor total_sal is select sum(sal) total_sal,deptno from emp1 group by deptno;
  dept_s dept_sal%rowtype;
begin
  -- delete from dept_sal;
  for dept_s in total_sal loop
    update dept_sal set total_sal=dept_s.total_sal where deptno=dept_s.deptno;
    -- insert into dept_sal values(dept_s.deptno,dept_s.total_sal);
  end loop;
  -- 不要新增commit;
EXCEPTION
  when OTHERS THEN rollback;
end;
建立DML觸發器  偽記錄 ":old"和":new"    ":old" 代表操作完成前的舊記錄    ":new" 代表操作完成後的新記錄  在執行三種DML語句時 ":old"和":new"的存在情況     建立行級觸發器 (for each row)應用例項: 在表emp_sal與emp1表關聯,建立觸發器 當emp1表中一個人的工資發生改變時,記錄該事件
--當有人的工資發生改變時,需要做記錄
create or replace trigger emp_sal_trigger
after update on emp1
for each row --行級觸發器
begin
  insert into emp_sal values(:old.empno, :new.sal, emp_sal_seq.nextval,sysdate,:old.sal);
exception
  when others then dbms_output.put_line('新增失敗');
end;
測試程式碼:
update emp1 set sal = sal*1.1;  --指定行級觸發器
commit;
注意:觸發器中不能有commit和rollback語句

觸發器中的謂詞

 

應用例項:

--當有人的工資發生改變時,需要做記錄
--當公司多了一個僱員的時候,新增記錄中只有新的工資(沒有old.sal,沒有new.sal)
--當有人離職時,需要把該員工的工資修改記錄刪除
create or replace trigger emp_sal_trigger
after update or insert or update on emp1
for each row --行級觸發器
begin
  if updating
    then insert into emp_sal values(:old.empno, :new.sal, emp_sal_seq.nextval,sysdate,:old.sal);
  elsif inserting
    then insert into emp_sal values(:new.empno,:new.sal,emp_sal_seq.nextval,sysdate,0); 
  else
    delete from emp_sal where empno=:old.empno;
  end if;
exception
  when others then dbms_output.put_line('新增失敗');
end;
測試程式碼:
--執行(測試)語句
--新增一條資料
insert into emp1 values(9527,'TOM','CLERK',7902,sysdate,1200,null,20);
COMMIT;

--修改工資
UPDATE emp1 set sal=sal*1.5 where empno=9527;
COMMIT;

--員工離職
delete from emp1 where empno=9527;
COMMIT;
對觸發器本身的刪除和修改
--觸發器禁用
alter trigger emp_sal_trigger disable;
--觸發器開啟
alter trigger emp_sal_trigger enable;
--刪除觸發器
drop trigger emp_sal_trigger;
--查詢當前使用者的所有觸發器
select * from user_triggers;
執行結果:


索引(給資料加目錄)   當資料庫表中存在很多條記錄,如大於10萬條時,查詢速度便成為一個問題   在書中查詢某內容時,首先在目錄中查詢所需知識點,然後根據目錄中提供的頁碼找到要查詢內容,大大縮短了查詢時間。 可以建立類似目錄的資料庫物件,實現資料快速查詢,這就是索引。   按照索引的儲存結構分類  B樹索引(重點)  點陣圖索引  反向鍵索引 按照索引值是否唯一分類  唯一索引  非唯一索引 按索引列分類  單列索引  組合索引  基於函式的索引
索引的語法:   
/*
  主鍵約束/唯一約束 : 系統會自動建立索引,以SYS_開始
  1. 為一個表的列或組合列建立索引後,讀取的速度加快
  2. 但寫的速度卻減慢了,因為插入,修改和刪除資料後,還要更新索引
  3. 索引也需要空間,系統要佔用大約為表1.2倍的硬碟和記憶體空間來儲存索引,增加了空間負擔
  
  索引建立的原則
  1. 在大表上建立索引才有意義
  2. 在where子句或是連線條件上經常引用的列上建立索引
  3. 索引的層次不要超過4層
  
  提高查詢效率是以消耗一定的系統資源為代價的,索引不能盲目的建立,這是考驗一個dba是否優秀的很重要的指標
  
  索引分類:
  1. 按照資料儲存方式,分為B*樹,反向索引,點陣圖索引
  2. 按照索引列的個數分為,單列索引,複合索引
  3. 按照索引列值的唯一性,分為唯一索引和非唯一索引
  此外還有函式索引,全域性索引,分割槽索引等.
*/

--檢視有多少張表
select * from user_tables;

--查看錶t10結構
select column_name,data_type,data_length,nullable,data_default from all_tab_columns where lower(table_name)='t10';

--查看錶t10內容
select * from t10 ;

--建立索引
create index idx_t10_name on t10(name);

--刪除索引
drop index idx_t10_name;

--檢視所有索引(從字典資料表中查詢)
select index_name,table_name from user_indexes where lower(index_name)='idx_t10_id_name' ;

--建立複合索引
create index idx_t10_id_name on t10(id,name);
--在pet表的adopt_time欄位上建立降序唯一索引adopt_time_index
create unique index adopt_time_index on pet(adopt_time desc);
--在pet表的type_id欄位上建立點陣圖索引type_id_bitmap_index
create bitmap index type_id_bitmap_index on pet(type_id);
--在pet表的health、love欄位上建立組合索引health_love_index
create index health_love_index on pet(health,love);
--建立基於函式TO_CHAR(adopt_time,'YYYY')索引to_char_index
create index to_char_index on pet(TO_CHAR(adopt_time,'YYYY'));
--在pet表的master_id 欄位上建立反向鍵索引master_id_reverse_index
create index master_id_reverse_index on pet(master_id) reverse;
--刪除在pet表上建立的反向鍵索引master_id_reverse_index
drop index master_id_reverse_index;
建立索引的列的特點:

  1.經常需要搜尋的列
  2.主鍵列

  3.經常用在連結的列

  4.經常需要根據範圍搜尋的列

  5.經常需要排序的列

  6.經常出現在where子句的列

不應該建立索引的列:

  1.查詢中很少使用或參考的列

  2.只有很少資料值的列

  3.定義為lob型別的列

  4.修改效能遠遠大於檢索效能

避免限制索引:

  1.避免使用不等操作符(<>、!=)

  2.避免使用is null or is not  null

  3.避免在where子句中使用函式

  4.避免在比較時使用不匹配的資料型別