SQL Server約束和觸發(fā)器的區(qū)別
SQL Server約束相信大家都比較了解了,那么,SQL Server約束和觸發(fā)器的區(qū)別在哪里呢?
在SQL Server數(shù)據(jù)庫中提供了兩種主要機制來強制使用業(yè)務(wù)規(guī)則和數(shù)據(jù)完整性,他們是SQL Server約束和觸發(fā)器。觸發(fā)器其實就是一個特殊類型的存儲過程,可在在執(zhí)行某個操作時自動觸發(fā)。觸發(fā)器與約束都可以實現(xiàn)數(shù)據(jù)的一致性。那么他們在使用的過程中,有哪些差異呢?簡單的來說,觸發(fā)器可以實現(xiàn)約束的一切功能。但是在考慮數(shù)據(jù)一致性問題的時候,首先要考慮通過約束來實現(xiàn)。如果約束無法完成的功能,則再通過觸發(fā)器來解決。兩者從功能上來說,他們的關(guān)系如下圖所示:
觸發(fā)器可以包含使用SQL代碼的復(fù)雜處理邏輯。如果單從功能上來說,觸發(fā)器可以實現(xiàn)約束的所有功能。但是由于其自身的種種缺陷,其往往不是實現(xiàn)數(shù)據(jù)一致性等特定功能的***解決方案。總的來說,只有在約束無法實現(xiàn)特定功能的情況下,才考慮通過觸發(fā)器來完成。這只是在處理約束與觸發(fā)器操作過程中的一個基本原則。對于他們兩個具體的差異筆者在下面也進行了比較詳細的闡述。歡迎大家進行補充。
差異一:錯誤信息的管理上。
當違反系統(tǒng)的SQL Server約束規(guī)則時,需要向用戶返回一定的錯誤信息,方便用戶進行排錯。約束與觸發(fā)器在遇到問題時都可以返回給用戶一定的錯誤信息。但是,約束只能夠通過標準化的系統(tǒng)錯誤信息來傳遞錯誤消息。如果應(yīng)用程序需要使用自定義消息和較為復(fù)雜的錯誤處理機制,則必須要使用觸發(fā)器才能夠完成。如現(xiàn)在數(shù)據(jù)庫中有一張產(chǎn)品信息表。為了保證產(chǎn)品的唯一性,要求產(chǎn)品的編號必須唯一。如果用戶輸入的產(chǎn)品編號跟企業(yè)現(xiàn)有的產(chǎn)品編號有重復(fù)的話,這條產(chǎn)品信息就不能夠被保存。從技術(shù)上來說,約束與觸發(fā)器都可以實現(xiàn)這個需求。但是,當違反這個唯一性規(guī)則時,他們提供的錯誤信息是不同的。
如利用約束來實現(xiàn)這個唯一性控制,那么當用戶輸入重復(fù)的編號時,則系統(tǒng)會提示違反了唯一性規(guī)則,不允許保存。但是光憑這條消息的話,可能用戶還不能夠馬上了解是怎么回事情。有時候程序員希望能夠返回更加具體的信息。如在產(chǎn)品基本信息表中可能有多個字段具有唯一性約束,那么用戶希望知道到底是哪個字段違反了唯一性約束。如用戶現(xiàn)在輸入產(chǎn)品編號為DT001的產(chǎn)品編號時出現(xiàn)了這個錯誤。那么用戶可能希望系統(tǒng)能夠顯示出系統(tǒng)中原來存在的DT001這個產(chǎn)品的具體信息,如他的規(guī)格描述、產(chǎn)品名稱等等。這可以幫助員工來判斷自己要建立的產(chǎn)品信息是否真的跟原來存在的產(chǎn)品信息重復(fù)。還是只是產(chǎn)品編號的重復(fù)而已。如果要在錯誤信息中帶出更加詳細的信息,則數(shù)據(jù)庫管理員不得不采用觸發(fā)器來對這個唯一性進行控制。因為只有觸發(fā)器可以返回數(shù)據(jù)庫管理員自定義的錯誤信息;而且還可以實現(xiàn)比較復(fù)雜的邏輯控制。而約束只能夠范圍系統(tǒng)定義的標準錯誤信息。
另外如果違反一些主鍵、外鍵約束的話,系統(tǒng)也只會提示標準的錯誤信息。而不會提示到底是哪一張表中存在子記錄等等詳細的錯誤信息。這就給用戶排錯的時候帶來不必要的麻煩。因為它需要先去查找這個約束或者主鍵的名字,然后再去看具體的約束定義才能夠確定到底是哪里出了問題。但是普通用戶往往是不能夠看到約束的具體定義的。故在遇到這種情況時,***也能夠通過觸發(fā)器來提供比較詳細的錯誤信息,以提高應(yīng)用程序的友好性。
差異二:性能上的差異分析。
如現(xiàn)在有兩張表,分別為銷售訂單頭與銷售訂單行。在銷售訂單中有一個訂單ID,它是這張表的主鍵,也是銷售訂單行表的外鍵?,F(xiàn)在如果更改了銷售訂單頭表的主鍵的值,那么必須要保證銷售訂單行表中訂單ID的值也隨之更改。否則的話,銷售訂單頭表與銷售訂單行表就無法對應(yīng)起來。此時觸發(fā)器與約束都可以實現(xiàn)類似的功能。觸發(fā)器可以將銷售訂單頭ID的更改通過級聯(lián)更新的功能傳播給數(shù)據(jù)庫中其他相關(guān)的表,實現(xiàn)級聯(lián)更新。約束也可以實現(xiàn)類似的功能。而且通常情況下,通過級聯(lián)引用完整性約束可以更有效的執(zhí)行這個級聯(lián)更新。如當上面這個更改發(fā)生后,觸發(fā)器可以禁止或回滾違反引用完整性的更改,從而取消所嘗試的數(shù)據(jù)修改。當更改外鍵且新值與其主鍵不匹配時,這個的觸發(fā)器將生效。但是,數(shù)據(jù)庫中有一個現(xiàn)成的解決方案,即FOREIGN KEY 約束通常用于此目的。如果觸發(fā)器表上存在約束,則在 INSTEAD OF 觸發(fā)器執(zhí)行后但在 AFTER 觸發(fā)器執(zhí)行前檢查這些約束。如果違反了約束,則回滾 INSTEAD OF 觸發(fā)器操作并且不執(zhí)行 AFTER 觸發(fā)器。
遇到這種情況后,往往就是兩種處理方式。一是如果要更改的主鍵在其他表中已經(jīng)存在的話,那么就不允許其進行更改,系統(tǒng)會拒絕保存或者回滾用戶的更改操作。二是如果要更改的主鍵信息在其他表中已經(jīng)存在相關(guān)的記錄,而數(shù)據(jù)庫管理員又允許其更改的話,為了保證數(shù)據(jù)的一致性,就要出發(fā)級聯(lián)更新的功能。讓數(shù)據(jù)庫系統(tǒng)在更改主鍵的同時自動更新其他表中的相關(guān)信息。無論采取哪種方式,從性能上來說,約束的執(zhí)行性能都要高一點。而且系統(tǒng)本身就提供了一些約束規(guī)則,如級聯(lián)引用完整性約束的等等。故也省去了管理員寫觸發(fā)器代碼的工作量。不過有一點值得說明的是,雖然約束的執(zhí)行性能比較高,但是其向用戶提供的錯誤信息確實非常有限的。如上面***點所說,系統(tǒng)只提供了一些標準的錯誤信息。如果管理員需要向用戶提供比較詳細的錯誤信息,則需要通過觸發(fā)器的自定義錯誤信息來實現(xiàn)。故在用戶的友好性與數(shù)據(jù)庫的執(zhí)行性能之間,數(shù)據(jù)庫管理員需要做出一個均衡。
差異三:管理維護的工作量。
由于約束基本上都是數(shù)據(jù)庫現(xiàn)成的解決方案。無論是索引約束還是外鍵約束,又或者是check約束。往往在數(shù)據(jù)庫系統(tǒng)中已經(jīng)有了現(xiàn)成的解決方案。數(shù)據(jù)庫管理員通過直接引用這些解決方案即可以實現(xiàn)特定的功能,而不用再費力的編寫觸發(fā)器來實現(xiàn)。如要實現(xiàn)表中某個字段的唯一性約束,則只需要直接在這個字段上啟用unique約束即可。從而省去了編寫觸發(fā)器代碼的時間。所以通常來說,觸發(fā)器的維護工作量要比約束來的多。因為觸發(fā)器中系統(tǒng)沒有現(xiàn)成的可以引用,而都需要數(shù)據(jù)庫管理員通過實際清理來進行編寫。如果不熟悉編制的話,還很容易引起不必要的錯誤。為此,如果單從這個工作量來考慮的話,那么數(shù)據(jù)庫管理員肯定喜歡采用這個約束,而不喜歡采用觸發(fā)器。
最終的建議:
如果約束能夠?qū)崿F(xiàn)特定的功能,則數(shù)據(jù)庫***能夠采用約束而不是觸發(fā)器。因為約束能夠提供比較高的執(zhí)行性能,而且數(shù)據(jù)庫管理員維護的工作量也會小得多。如實體完整性應(yīng)在***級別上通過索引進行強制,這些索引可以是PRIMARY KEY約束和UNIQUE約束的一部分,或者是獨立于約束而創(chuàng)建的。域完整性可以通過CHECK約束進行強制,而引用完整性則可以通過FOREIGN KEY約束進行強制。當然使用約束的前提是假設(shè)這些約束的功能能夠滿足應(yīng)用程序的功能需求。
如果系統(tǒng)中現(xiàn)成的約束無法滿足企業(yè)用戶的需求,如功能無法滿足或者提供的錯誤信息不夠等情況,此時數(shù)據(jù)庫管理員就需要通過觸發(fā)器來完成。不過數(shù)據(jù)庫管理員在編寫觸發(fā)器的時候,仍然可以借鑒相關(guān)約束的實現(xiàn)方式。而不用從零開始,來重新設(shè)計觸發(fā)器。另外 觸發(fā)器可以防止一些惡意或錯誤的記錄插入、刪除以及更新操作,并強制執(zhí)行比CHECK約束定義的限制更為復(fù)雜的其他限制。其還可以提供比CHECK約束更復(fù)雜一點的功能。如觸發(fā)器可以引用其他表中的列。
可見觸發(fā)器與約束各有各的特點。數(shù)據(jù)庫管理員要從執(zhí)行性能、維護工作量、實現(xiàn)的功能、用戶友好性等多個方面出發(fā),選擇合適的處理方式。
【編輯推薦】