[英]How to use database triggers in a real world project?
我在最后的弱點中學到了很多關於觸發器和活動數據庫的知識,但我對這些真實世界的例子有一些疑問。
在工作中,我們使用帶有 ASP.Net 和 MSSQL 服務器的實體框架。 我們只使用自動生成的約束,不使用觸發器。
當我聽說觸發器時,我問自己以下問題:
觸發器可以執行哪些任務? 例如:報告數據的生成:目前報告的數據是在 vb 中創建的,但我認為觸發器也可以處理這個問題。 vb 中的創建需要很多時間,用戶應該不需要等待,因為這對他的工作來說不是必需的。 這是觸發器完美任務的示例嗎?
OR-Mapper 如何處理觸發器操縱的數據? 例如:OR-Mapper 是否識別觸發器是否操縱了數據? 實體框架似乎緩存了很多數據,所以我不確定如果觸發器操作數據,在處理框架的插入/更新/刪除后它是否讀取更新的數據。
數據庫中應該有多少約束處理? 例如:有時數據庫中的約束看起來比上面的層(vb.net,...)更容易和更快,但是如何將異常拋出到可以由OR-Mapper 處理的上層? 在任何 OR-Mapper 中處理 SQL 異常(來自觸發器)是否有一個好的解決方案?
提前致謝
當您聽說一種新工具或新功能時,並不意味着您必須在任何地方都使用它。 您應該考慮應用程序的設計。
當邏輯在數據庫中時,觸發器被大量使用,但是如果您在數據庫之上構建 ORM 層,您希望業務層中的邏輯使用 ORM。這並不意味着您不應該使用觸發器。 這意味着您應該以與存儲過程或數據庫函數相同的方式將它們與 ORM 一起使用 - 僅當它有意義或提高性能時。 如果你將大量邏輯傳遞給數據庫,你可以扔掉 ORM 甚至整個業務層,並使用兩層架構,其中 UI 將直接與數據庫對話,數據庫將完成你需要的一切——這樣的架構被認為是“舊的”。
StoreGeneratedPattern.Identity
或StoreGeneratedPattern.Computed
進行設置 - EF 完全遵循邏輯在數據庫或應用程序中的模式。 一旦您定義了在數據庫中分配的值,您就無法在應用程序中更改它(它不會持久存在)。我使用觸發器有兩個主要目的:審核和更新修改/插入時間。 審計時,觸發器將數據推送到相關的審計表。 這不會以任何方式影響 ORM,因為這些表通常不會映射到主數據上下文中(需要查看審計數據時會使用單獨的審計數據上下文)。
在記錄/修改插入/修改時間時,我通常將 model 中的這些屬性標記為[DatabaseGenerated( DatabaseGenerationOptions.Computed )]
日期時間字段正確。
我以這種方式管理審計和這些日期並不是硬性規定。 有時我需要比數據庫本身可用的更多的審計信息,而是在數據層處理審計。 有時我想強制應用程序更新日期/時間(因為它們可能需要在同時更新的多個行/表中保持相同)。 在這些情況下,我可能使字段可為空,但 model 中的[Required]
強制在 model 可以保留之前設置日期/時間。
觸發器用於維護數據的完整性和一致性(通過使用約束),幫助數據庫設計者確保完成某些操作並創建數據庫更改日志。
例如,給定數字輸入,如果您希望值被限制為小於 100,您可以編寫一個觸發器,在更新或插入時為每一行觸發,並在該列的值不小於 100 時引發應用程序錯誤滿足那個約束。
假設您要記錄對表的歷史更改。 您可以創建一個在每次插入、更新和刪除后觸發的觸發器,它還會將數據插入到日志記錄表中。 如果您需要執行自定義自定義邏輯,那么觸發器可能會吸引您。
舊的 Infomodeler/Visiomodeler ORM(不是你想的 - 它是 Object 角色建模)在生成物理 model 時提供了一個替代方案。它將提供所有帶有觸發器的參照完整性。 有兩個原因:
因此,與 model 相關的觸發邏輯與任何 RI 約束的方式相同。 在 SQL 服務器中,它使用 RAISERROR 處理違規。
觸發器的一個概念性問題是它們本質上是上下文無關的——無論上下文如何,它們總是觸發(至少沒有很大的痛苦,你最好將它們的邏輯包含在上下文特定邏輯的 rest 中。)所以全局域約束是我發現它們唯一有用的地方——我想這是識別“參照完整性”的另一種通用方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.