簡體   English   中英

SOLID存儲過程和函數

[英]SOLID stored procedures and functions

我想在我正在使用的應用程序中開始更多地使用存儲過程。 該應用程序搜索十幾個數據庫。 應用程序將信息存儲在自己的數據庫中。

我正在考慮將業務邏輯偏移到特定數據庫中的存儲過程。 因此,如果邏輯對所有外部數據庫都是通用的,則將其保存在應用程序(.NET)中。 如果邏輯特定於數據庫,則創建存儲過程。

我不確定SOLID如何與存儲過程和函數一起工作,因為沒有接口或抽象。 以下帖子似乎建議您應該嘗試合並查詢: http//ledgersmbdev.blogspot.co.uk/2013/02/building-solid-databases-interface.html 例如,如果存儲過程有四個SQL語句,那么為什么不嘗試將它們組合成一個SQL語句呢? 這是帖子的意思嗎? 這是一種SOLID方法嗎?

我正在考慮將業務邏輯偏移到特定數據庫中的存儲過程。 因此,如果邏輯對所有外部數據庫都是通用的,則將其保存在應用程序(.NET)中。 如果邏輯特定於數據庫,則創建存儲過程。

這句話引起了我的極大關注。 當你說邏輯是特定於數據庫時,我認為你指的是上述十二個中的一個,這是一個設計缺陷。 數據庫只是信息存儲,它們不應該要求任何“特殊”邏輯來訪問它們在任何視圖結構之外。 此外,如果需要以非設置方式操作數據,而不是將其放入應用程序中。 當它們可以偏移到您的應用程序時,這不會使您的執行計算。

在設計應用程序時,必須確保不要變形數據庫以忽略關系模型。 根據我的經驗,這是使您的應用程序無法管理和緩慢的最佳方法之一。 為了澄清,業務邏輯不應該住在數據庫中,這使得它很難為他人使用您的數據。 反對這一點的典型論點是,“我是唯一一個使用數據的人”,我說這是一個可怕的設計理由。

繼續,您應該嘗試確定關系(集)模型中實際工作的內容,並構建可以查詢該數據的應用程序。 而不是構建適合您的應用程序的數據庫。 話雖這么說, SOLID 不與關系模型一起工作 ,因為它們不是面向對象的
WIKI

在計算機編程中,SOLID(單一責任,開放式閉合,Liskov替換,接口隔離和依賴性反轉)是Michael Feathers在早期由Robert C. Martin 1 [2]確定的“前五條原則”中引入的助記符縮寫。 2000s [3]代表了面向對象編程和設計的五個基本原則。

評論的更新

應用程序鏈接來自不同系統的信息,並決定何時可以刪除一組記錄(這些是適用於所有系統的通用規則)。 然后,在刪除之前必須應用特定於數據庫的規則。 我在考慮將本地業務規則與存儲過程相抵消。 -

看一下這個評論,我不完全理解在審計/軟刪除之外的數據庫特定規則。 我同意數據庫特定的規則可以設置為數據庫中的管理存儲過程,當你遇到如下問題時,必須繪制該行:

我的應用程序會查詢歷史數據,除非它超過6 months然后必須從脫機存儲中檢索。

6 months后刪除此數據的選項是允許應用程序通過某些業務邏輯清除它或創建計划任務來執行此清理,因為它是刪除元組的正常數據庫操作。

我在這里的論點是將它放在數據庫中,並禁止你的應用程序調用這些過程。 實際上,您的應用程序甚至不應該知道數據庫存在於正確抽象的應用程序中。 因此,如果這是您提出的示例,那么我的解決方案如下:

1) Create stored procedures in the database that only a maintenance based user can invoke,   NOT THE APPLICATION  
2) Create a database scheduled task to run these based on your data needs.  

我同意不將業務邏輯放入SQL的概念以及SQL作為基於集合的語言的概念。

將SOLID視為一些非常好的編程實踐的OO特定實現,並將它們應用於您編寫的任何代碼,包括SQL。 良好的表格模式設計將包含SOLID創意。

我花了太多時間調試大型復雜的存儲過程,所以如果你能避免它,請做。 如果您必須編寫存儲過程代碼,那么SOLID可以幫助您。

例如,我有一個大型存儲過程,它會查詢幾十個表,並返回一個數據集,供打印機用來發送“歡迎信” 這是一個偽裝成“報告”並用SQL編寫的業務流程的典型示例。

從SOLID鏡頭看這個操作:

它應該有一個單一的責任和一個改變的理由。

代碼既可以確定誰收到一封信,也可以確定該信中的數據。 如果流程的任何一個方面發生變化,您必須更新並重新測試整個系統。 一個堅實的原則是擁有一個確定誰得到一封信及其中的內容的功能。

這可能就像擁有一個返回客戶列表的查詢一樣簡單。 將其作為ID或TVP數組饋送到另一個存儲過程以收集數據。

打開關閉

在大多數SP(存儲過程)代碼中,整個過程是硬編碼或“數據驅動”。 數據驅動通常是針對此原則的SQL工作。 SQL流程通過一個CASE來修改,這個CASE在字段值或SQL中獲得EVAL的文本字段。

我們剛剛創建的' master'SP中可以看到我的問題的SOLID方法現在我有一個調用GET_CUSTOMERS的SP和另一個調用GET_DATA的SP 主人基本上控制工作流程,工作流程不應更改。 主人關閉進行修改。

如果我們需要增強系統以發送電子郵件,並且電子郵件具有不同的數據字段,那么我可以通過調用GET_DATA_FOR_EMAIL將調用交換到GET_DATA 打開修改

主人有一個責任。 如果工作流程發生更改,則此主服務器會根據規則#1進行更改。

利斯科夫替代原則

這是非常OO,但為了說明一點,我們可以說GET_CUSTOMERS SP在這里被視為可替換的對象。 我應該能夠進行不同的查找,例如GET_CUSTOMERS_WHO_NEED_DIFFERENT_LETTER,並且能夠重用我的代碼。 或者也許是GET_CUSTOMERS_FOR_INTERNAL_TEST 如果系統的所有組件都是一次性且不可重復使用,那么系統將難以維護和理解。 這可能是一個延伸。 少考慮OO對象繼承,更多地考慮具有可重用的類似參數的函數。

依賴倒置原則

這是我見過的最大失敗。 不要在selection和where子句周圍編寫代碼。 我的系統開始時使用* SELECT * FROM表,table,table,其中customers.letter-sent = false *(實際超過1k行)我希望以查找所有客戶並向他們發送信件結束 從抽象和代碼開始,最高級別控制SP中的工作流程。

我們的想法是抽象是“找到客戶”並返回客戶列表。 我應該能夠將該邏輯交換為代碼中的其他內容。 我經常看到的違反這種情況的方法是讓一個“查找客戶”寫入連接在customers表上的表,然后是另一個讀取該表的SP。 在這種情況下,您的抽象泄露到實現中,您從可重用代碼轉到為特定表發送字母的系統。

SQL非常強大,並且很容易將在抽象中應該分開的步驟組合在一起來實現。

存儲過程是一個很好的工具,可以幫助團隊交換性能的可讀性,並以可擴展性為代價帶來便利。 它仍然是代碼,並且從其他語言中竊取模式只會對您的整體設計有所幫助。

如果您的需求很簡單,通常您不需要設計模式。 如果您的代碼超過50行左右,請嘗試將其移至應用層和/或考慮可靠的重新分解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM