審慎而明智地使用SQL觸發器

2021-05-25 15:43:57 字數 1434 閱讀 6828

觸發器可以說是資料庫中的常用工具,不過,這個功能是否被合理利用,也在一定程度上影響了最終成品的各方面效能。

要想把說明觸發器的適用範圍,就得先說說觸發器本身具有哪些特點:

基於觸發器的上述特點,並站在乙個軟體全域性的角度來看,觸發器應該保持對於開發人員的透明性,也就是說,開發人員應當始終不需要知道某個觸發器正在對業務邏輯產生影響。

最好的做法就是,使用觸發器時,避免使其影響業務邏輯本身,曾經在教科書上看到這樣乙個例子:

有乙個學生選課情況表,欄位有學號、課程號、平時成績、考試成績、總評成績。需要設計乙個觸發器,當學生的平時成績或考試成績修改時,就自動按照平時成績20%和考試成績80%的比例計算出總評成績。

實際上這應該是個反面教材,這個使用情形就是剛才所說的觸發器干涉了業務邏輯。那麼為什麼不要讓觸發器干涉業務邏輯呢?

開發人員站在整個資料庫的外側,也就是關注到資料庫的外模式,而不關心或無權過問概念模式和內模式,觸發器屬於概念模式範疇(甚至可能是更低的層次),不需要被開發人員所了解。那麼,觸發器對於業務邏輯的干涉將使開發人員對於結果產生困惑,為什麼開發人員在看似不完整的資料操作之後(修改了平時成績或考試成績後沒有修改總評成績),卻得到了完整的結果。這個說法建立在表「充當」外模式使用的前提下。

另一方面,觸發器帶來了程式設計師無法控制和了解的業務邏輯,使得軟體測試最終變得困難重重,如果有乙個bug出現在觸發器中,那麼它可能將最後才能被發現,此時已經帶來了高額的測試和除錯成本。對於資料庫管理員也是如此,由於儲存過程和觸發器處於dbms三層模型中的不同位置,所以當檢查外模式的儲存過程的業務邏輯時,也同樣會產生不必要的困惑。更嚴重的情況是,一旦儲存過程與相關的觸發器單方面進行了改動,最壞的情況可以導致業務崩潰,因為不同層級之間的高耦合帶來難以預料的維護上的災難。

對於上面這個簡單的問題,其實使用檢視就可以很容易地解決,總評成績=平時成績×20%+考試成績×80%,這樣的簡單關係通過檢視,也不會顯著產生效率問題,因為計算不涉及多表。對於涉及許多表而可能影響效率的情況,可以採用儲存過程來包裝對於平時成績或者考試成績的變更,當然對於支援物化檢視的dbms,也可能是不錯的選擇。

教材上還有乙個例子,也針對上面那張表:

設計乙個觸發器,當刪除一條學生的選課記錄時,自動在另一張與此表結構一致的備份表中插入這條被刪除的記錄。

這個例子可以被認為是正確地使用了觸發器,它與業務邏輯無關了,即使這個觸發器不存在,業務也可以照常進行下去,因為備份表對於開發人員而言實際上也是透明的,只是基於資料可靠性和系統效能考慮而增加的關係,與觸發器搭配使用再恰當不過。

另乙個使用觸發器的場合是統計資訊,例如記錄使用者登入失敗的操作、記錄使用者的操作習慣等等。

但是記得別再一張表上建立太多的觸發器哦,否則這張被無數觸發器監視起來的表,一旦需要執行dml操作,效能就嚴重受到影響了。

本文在cc by-sa(署名-相同方式共享)協議下發布。

C 明智而審慎地使用多重繼承

20180327 c 明智而審慎地使用多重繼承 當多重繼承 multiple inheritance,mi 運用到程式設計中時,程式有可能從乙個以上的基類繼承相同的名稱 如函式,typedef等 那會導致較多的歧義,eg class borrowableitem class company clas...

sql觸發器的使用

觸發器的幾條效果語句 after在觸發事件之後 befor 在觸發器之前 insert 觸發的條件 update 更新事件 delete 刪除事件 insert 插入事件 例項 delimiter 把語句結束符號換成 因為trigger中會用到 create trigger t1 after ins...

Sql 觸發器的簡單使用

觸發器的使用 觸發器在一次會話中,會產生兩張臨時表 1.deleteed 刪除動作臨時表,記錄刪除的資料。2.insert 插入動作臨時表,記錄插入的資料。3.觸發器不存在update 臨時表,因為update操作是先刪除,再插入。4.上面兩張臨時表,表結構和當前操作表結構是相同的。建立乙個觸發器。...