PP团队圣经巨著《Application Architecture Guide2.0》14章-数据访问层
第十四章?數據訪問層指導
概覽
這一章主要描述設計數據訪問層時要注意的主要原則。它們覆蓋了設計數據訪問層遇到的通常問題及錯誤。下面的圖表展示了數據層怎樣嵌入一個通用的應用架構。
?(cnblog我的圖片一直上傳不了,報Remote server Error,只能使用網絡圖片了)
?
數據訪問層組件
l???????? 數據訪問層組件。數據訪問層組件將訪問底層存儲介質的必要方法抽象出來。將數據訪問功能集中起來,可以使應用程式便于配置和維護。
l???????? Data Helpers/Utilities。Helper和Utilities功能幫助操縱,轉變和獲取數據。他們由一些特別的類庫組成以增強數據訪問性能以及減少邏輯組件和服務代理的開發要求。
l???????? 服務代理。當業務組件必須將功能通過外部服務暴露時,你可能需要創建程式管理通信服務所需要的協議。服務代理將你的程式從調用不同的服務中分離出來,并且提供額外的服務,如服務的數據格式和你的應用程式需要的格式之間的映射。
?
方法
正確的設計數據層可以減少程式部署后的開發和維護工作。這章會簡要的概述一個設計訪問層有效的方法。當設計數據層時使用下面的方式:
1.?????? 創建一個總體的設計。
A.??????? 確定數據源要求。
B.??????? 確定數據訪問方式。
C.??????? 選擇怎樣映射數據結構到數據源。
D.?????? 確認處理數據源錯誤時的策略。
E.??????? 確認怎樣連接數據源。
2.?????? 設計你的數據訪問層組件。
A.??????? 列舉你要訪問的數據源。
B.??????? 決定每一個數據源的訪問方式。
C.??????? 確認是否需要Hlper組件以簡化數據訪問組件開發和維護。
D.?????? 確認相關的設計模式。例如,考慮使用表格數據,查詢對象,Repository,以及其它模式。
3.?????? 設計你的數據訪問層Helper組件。
A.??????? 識別可以從數據訪問組件中拿出來通用的功能以重用。
B.??????? 研究可用的Helper組件。
C.??????? 考慮為連接字符串,數據源認證,監視以及異常處理設計自定義的Helper組件。
D.?????? 考慮實現數據訪問監視和測試你的Helper組件。
E.??????? 考慮實現你的Helper組件安裝和日志。
4.?????? 設計服務代理。
A.??????? 使用合適的工具以添加引用。生成一個代理和數據類來代表服務中的數據契約。
B.??????? 確認服務怎樣使用。對于大多應用程式來說,最好在業務層和數據訪問層之間使用一個抽象層,這樣會提供一個一致的接口而不考慮數據源。對于小的應用程式來說,業務層或者表示層,可以直接訪問服務代理。
?
設計原則
下面的設計原則包括了設計數據層時應該考慮的不同方面。章節的剩余部分會提供給你選擇合適的技術和設計模式的詳細信息。
l???????? 選擇數據訪問技術。合適的數據訪問技術選擇依賴于你處理的數據類型,以及你怎樣操縱程式數據。特定的技術會適用特別的場景。下面的部分討論了所選擇的數據訪問技術的好處以及缺點。
l???????? 使用抽象以實現和數據訪問層松耦合的接口。這個可以通過定義接口組件來完成,如眾所周知的輸入和輸出Facade,可以將請求翻譯為層組件可以理解的信息。另外,你可以定義接口或抽象基類,以被組件實現。
l???????? 考慮穩固的數據結構。如果你要在數據訪問層處理基于Table的實體,考慮使用DTO來幫助你把數據轉換為統一的結構,DTO鼓勵使用粗粒度的操作,以使數據在不同的邊界層移動。
l???????? 用數據訪問層封裝數據訪問功能。數據訪問層隱藏了訪問數據源的詳細信息,它用來管理連接,生成查詢,以及映射程式實體到數據源結構。數據訪問層的調用者使用自定義對象,Dataset,DataReader,以及XML文檔等抽象結構來交互。其它應用程序層使用操作更復雜的方式來操縱數據以滿足應用程式功能。分開的考慮可以幫助應用程式開發和維護。
l???????? 決定怎樣映射應用程序實體到數據源結構。應用程序使用的實體類型是最主要的決定因素。
l???????? 決定你怎樣來管理連接。實際上講,數據訪問層需要管理應用程序所有的數據源連接。你必須選擇合適的方法去存儲和保護連接信息以滿足應用程序的安全需要。
l???????? 決定你怎樣處理數據異常。數據訪問層應該捕獲以及處理所有和數據源、CRUD操作引起的異常。如果只是數據異常,數據源訪問及超時異常,數據訪問層應該處理。如果錯誤影響應用程式的功能或響應的話,那異常應該被傳遞到其它層。
l???????? 考慮安全風險。數據訪問層應該防止數據偷竊和破壞,保護訪問數據源的機制。應該使用“最少權限”的設計方法以限制需要執行的應用程式操作。如果數據源自己有能力限制權限的話,那數據訪問層和數據源都要考慮安全。
l???????? 減少數據包往返。考慮使用批處理命令以使用一個數據庫操作。
l???????? 考慮性能和客觀上可測量性。可測量以及性能在設計數據訪問層時就應該被考慮。例如,當設計一個基于網絡的商業程式,數據層性能是程式的瓶頸。當數據訪問層性能是決定性時,要限制昂貴的數據操作。
?
數據訪問層設計
| Category | Common Issues |
| BLOB | 不適當的在數據庫中存儲BLOBS以替代文件系統。 |
| ? | 對數據庫中的BLOB數據使用了不正確的類型。 |
| ? | 搜索以及操作BLOB數據。 |
| Batching | 沒有使用批處理以減少數據包往返。 |
| ? | Holding onto locks for excessive periods when batching. |
| ? | 沒有考慮使用批處理策略以減少數據庫數據包往返。 |
| Connections | 對連接池使用了不適當的配置。 |
| ? | 沒有處理連接超時和連接斷掉。 |
| ? | 執行的事務跨越過個連接。 |
| ? | 在過長的時間內保持連接打開。 |
| ? | 使用單獨的認證以代替全信任的子系統去訪問數據庫。 |
| Data Format | 選擇了錯誤的數據格式。 |
| ? | 沒有考慮串行化需求。 |
| ? | 沒有映射對象到關系數據存儲。 |
| Excepion Management | 沒有處理數據訪問異常。 |
| ? | 沒有對調用者掩蓋數據庫異常。 |
| ? | 沒有記錄致命性的異常。 |
| Queries | 使用字符串連接來組建查詢語句。 |
| ? | 查詢混合了業務邏輯。 |
| ? | 對于查詢語句沒有優化。 |
| Stored Procedures | 沒有正確的將參數傳給存儲過程。 |
| ? | 在存儲過程里實現業務邏輯。 |
| ? | 沒有考慮存儲過程里的動態SQL可以導致性能,安全以及可維護性。 |
| Transactions | 使用不正確的隔離等級。 |
| ? | 在多個數據源間使用了事務。 |
| ? | 使用了個別鎖,可能導致死鎖。 |
| ? | 允許長時間運行的事務導致鎖住了數據訪問。 |
| Validation | 對于數據字段沒有使用數據類型驗證。 |
| ? | 沒有處理NULL值。 |
| ? | 沒有過濾不正確的字符。 |
| XML | 沒有考慮怎樣處理非常大的XML DataSet. |
| ? | 沒有選擇合適的技術以方便XML和關系數據庫交互。 |
| ? | 沒有設置合適的索引導致沉重的XML查詢負擔。 |
| ? | 沒有使用Schema來驗證所有的XML輸入。 |
?
?
BLOB
BLOB是二進制的大型對象。如果數據以數據流的方式存儲或檢索,那它就是BLOB。BLOBs也許有結構,但顯然不是數據庫存儲的結構或者數據訪問層讀寫的結構。BLOB數據如果不能直接存儲在數據庫,則通常存儲在文件系統中。BLOBs典型的使用方式是存儲圖像數據,但也經常用于存儲以二進制為代表的對象。
?
當設計BLOBs策略時,考慮以下原則:
l???????? 當存儲圖像到硬盤不實際的時候,才會存儲到數據庫中。
l???????? 在服務器間使用BLOBs來簡化大型的二進制對象同步。
l???????? 考慮你是否需要搜索BLOB數據。如果需要的話,創建其它數據庫可搜索的字段來代替解析BLOB數據。
l???????? 考慮為BLOB數據使用文件系統以提高性能。數據庫的結構和實現決定著系統性能提升的高度。使用文件系統你還要考慮存儲和同步數據庫中的相關元數據。
l???????? 當檢索BLOB,把它轉換成業務層或表現層需要操作的合適類型。
l???????? 當使用緩沖傳輸的時候不要把BLOB數據存儲到數據庫中。
?
批處理
數據庫批處理命令可以提高數據訪問層的性能。在進入數據庫執行環境前要消耗比較多的資源。批處理可以減少前端花費以及提高吞吐量和減少響應時間。對相似的查詢使用批處理比較好,因為數據庫對相似的查詢會使用緩存以減少查詢執行計劃。
?
當設計批處理時,考慮以下原則:
l???????? 使用批處理以減少數據庫數據包往返以及減少網絡流量。
l???????? 為大量的相似查詢建立批處理可以獲得最大的效益。為不相似的或隨即的查詢建立批處理是無用的。
l???????? 使用批處理和命令以及DataReader以加載或拷貝多個數據集。
l???????? 當加載大量的基于文件的數據到數據庫時,使用BULK Copy工具。不要為長時間運行的批處理命令設置鎖。
?
連接
連接到數據源是數據訪問層的基礎。數據層必須管理所有的數據源連接。在數據層和數據源之間建立及管理連接都需要昂貴的資源。為了最大的提高性能,遵循下面的創建,管理和關閉連接原則。
l???????? 選擇一個策略以處理數據庫連接字符串。
l???????? 使用默認的連接池以減少活動的連接數量。
l???????? 確定連接沒有特別的不需要的字符。在效率不高的連接池里,多余的字符會使一些同樣功能的連接獲取到不同的值。
l???????? 在每一個事務后不要打開或關閉連接,考慮在一定的時間里保持連接以允許重用。在部署前,要模擬真實的負載情況來測試你的應用程式,對需要大量時間處理的地方做出改變以優化性能。
l???????? 不要以來垃圾回收器來釋放連接。在明確的地方盡快釋放它們。
l???????? 在可能的地方使用單一的連接來執行事務。
l???????? 設計Retry的機制以應付數據源丟失或連接超時的情況。
l???????? 由于安全原因,避免使用系統名或用戶數據源名(DSN)。
l???????? 考慮在配置文件里對連接信息加密。例如,使用.net內置的機制加密連接字符串。
?
數據格式
正確的數據格式用來合理的解釋數據庫的原始字節以形成數據層傳遞的信息。選擇適當的數據格式可以提高程式間的互操作性,簡化不同進程和機器間的串行化通信。數據格式和串行對于業務層存儲和檢索非常重要。
?
當設計數據格式時,考慮以下原則:
l???????? 為程式選擇合適的數據格式。
l???????? 在很多情況下,你需要使用自定義的數據或業務實體來提高程式可維護性。這需要額外的代碼來映射實體到數據庫操作。O/RM解決方案可以減少大量的自寫代碼。
l???????? 數據訪問層使用的數據結構不能包含業務規則。
l???????? 當使用經常改變的結構化數據時可以使用XML。
l???????? 決定數據的串行化需求。
l???????? 考慮互操作性需求。
?
異常管理
在數據庫中設計統一的異常管理策略。如果可能,在數據庫Helper組件中使用統一的異常處理邏輯。要特別注意在信任的層邊界發生的異常。設計不能處理的異常策略以使敏感的應用程式信息不會暴露。
?
當設計異常管理策略時,考慮以下原則:
l???????? 決定哪些異常可以呈現給調用者。死鎖,連接問題和網絡檢測可以在數據層解決。
l???????? 實現全局的異常處理以捕獲不可知的異常以及將它拋給原調用者。
l???????? 當通過服務接口來暴露數據層時,使用異常屏蔽信息以避免暴露敏感數據。
l???????? 在數據層中處理所有數據訪問相關的異常。
l???????? 考慮對數據源錯誤和操作超時實現Retry機制。
l???????? 告訴User異常會影響程式體驗。考慮將異常信息傳到業務層處理以及將它報告給User。
l???????? Log異常以容易的查找特定的錯誤。
l???????? 如果有多個數據源,記錄異常和錯誤的時候要包括單個數據源信息。
?
查詢
查詢是數據層主要的數據操作方式。它們將程式請求轉換為Create,Retrieve,Update和Delete(CRUD)數據庫操作。由于查詢是很基本的東西,所以應該優化查詢以最大的提高數據庫性能和吞吐量。
?
當設計數據層查詢,考慮以下的原則:
l???????? 當存儲過程不實用的時候使用SQL查詢語句。
l???????? 在SQL語句中使用參數以減少SQL注入。
l???????? 當需要動態的創建查詢,不要允許用戶輸入來決定查詢的詳細信息。
l???????? 在數據層中不要使用字符串拼湊來創建動態查詢。
l???????? 使用對象來創建查詢。例如,實現Query Object模式或使用ADO.NET對象。
?
存儲過程
存儲過程可以優化查詢性能以及提高安全。它比SQL語句提供了更高的性能因為數據庫可以針對它做出執行優化,并且可以根據存儲過程里的語句來優化數據庫。存儲過程也提供了額外的安全,因為調用者可以從它獲取數據而不用去數據庫表或者視圖里獲取。存儲過程同樣可以參數化以支持多個應用程式的復雜查詢。
?
當設計存儲過程,考慮以下原則:
l???????? 使用存儲過程來提高數據庫效率和數據層安全。
l???????? 使用Output參數來返回單個的值。
l???????? 避免動態SQL。當數據訪問是程式的瓶頸時盡可能的使用存儲過程。
l???????? 對于單個的數據輸入考慮使用單個的參數。
l???????? 對于列表形式的數據考慮使用XML參數。
l???????? 使用適當的事務來保持數據一致性。
l???????? 設計合適的異常處理返回錯誤以被應用程式處理。
l???????? 在存儲過程里避免實現業務邏輯。
l???????? 當處理數據時避免創建臨時表。而且,在內存中創建、使用臨時表比在磁盤中好。
?
事務
事務是將一系列的數據庫操作作為一個原子單元聯系起來以滿足請求和保證數據庫一致性。當所有動作的信息完成以及數據庫的數據永久性更改代表了事務結束。事務可以在發生的錯誤的時候回滾數據庫以保證數據庫的ACID屬性。
?
當設計事務時,考慮以下原則:
l???????? 在需要的時候使用事務。例如,對于一個單獨的SQL語句不需要使用事務,因為SQLSERVER可以自動將每一個SQL操作作為一個事務來執行。
l???????? 保持事務盡可能的短以減少鎖住的時間。
l???????? 使用合適的隔離等級。數據一致性的平衡是很有爭議的。高隔離級可以在并發的時候提供高的數據一致性。低隔離級可以通過降低一致性的花費而提高性能。
l???????? 如果針對一個數據庫執行事務,可以使用人工控制的事務。
l???????? 如果一個單獨的事務跨越了多個數據庫,那你應該使用自動的事務。
l???????? 避免混合人工控制和自動的事務。
l???????? 如果使用人工控制的事務,考慮在存儲過程里實現事務。
l???????? 考慮在事務里使用MARS來加強并發以避免潛在的死鎖問題。
l???????? 如果執行多條Insert,Update和Delete,將他們在一個事務里處理以獲取更好的性能。
?
驗證
設計一個有效的輸入和數據驗證策略對你的程式安全至關重要。決定從其它層,第三方組件,數據庫或數據存儲獲取的數據驗證規則。你可以驗證任何在你信任的邊界中通過的數據。
l???????? 驗證數據層中調用者發出的所有數據。
l???????? 驗證所有從數據庫中檢索的數據。
l???????? 你可以驗證任何在你信任的邊界中通過的數據。
l???????? 決定其它層的驗證方式。如果數據已經是可信的數據,那沒必要重復驗證。
l???????? 當設計驗證時考慮數據輸入的目的。
l???????? 在執行數據庫Update前驗證所有的數據。
l???????? 當驗證失敗的時候返回警告信息。
?
XML
XML在數據庫外是維護數據結構的很有用的方式。由于性能原因,在大量數據集時小心使用XML。使用Schema去驗證XML結構和內容。
?
當設計XML使用時,考慮以下原則:
l???????? 使用XML讀寫器去訪問XML格式的數據。
l???????? 使用XML Schema來定義數據存儲格式和傳遞。
l???????? 用適當的Schema來驗證接收到的XML。
l???????? 在XML Schema里為復雜的數據參數使用自定義的驗證。
l???????? 用特定類型的列來存儲XML,如果可能的話,使用數據庫來獲取最大的性能。
l???????? 對于讀Sqlserver里XML數據比較頻繁的程式,考慮使用XML索引。
?
管理注意點
當設計管理策略時,考慮以下原則:
l???????? 仔細考慮你是否需要創建自定義的實體或者其它數據表示可以更好的滿足需求。開發自定義的實體會加重開發負擔。通常,自定義實體是為了方便開發者定制。
l???????? 從一個基類派生業務實體可以提供基本的功能和封裝通用的Task。
l???????? 依靠為復雜數據使用內置的DataSet或XML Document來代替內部的集合,結構和其它編程結構。
l???????? 實現一個通用的集合接口以從你的業務實體暴露通用的功能集合。
l???????? 設計業務實體依賴于用于數據庫交互的數據訪問組件。統一實現數據訪問策略和相關的業務邏輯。例如,如果你的業務實體直接訪問SQLSERVER,那所有部署的程式客戶端使用的業務實體都需要SQL連接和驗證策略。
l???????? 使用存儲過程來從潛在的數據Shema中抽象數據訪問。小心不要過度使用存儲過程因為它會降低代碼維護和重用,包括存儲過程維護。過度使用的癥狀就是大量的存儲過程互相調用。避免使用它們來實現控制流,操縱單個的值以及一些在T-SQL中難以實現的功能。
?
性能考量
數據層設計及數據庫設計都要考慮性能。在調節系統吞吐量的時候考慮以上兩點。
?
當設計性能策略時,考慮以下原則:
l???????? 考慮改變數據查詢隔離級別。如果你在創建一個高吞吐量的程式,特殊的數據操作業務可能會在較低的隔離級執行。混合的隔離級別會影響系統數據的一致性,因此你要通過一個個實際例子小心的分析它。
l???????? 考慮批處理命令以減少數據庫的數據包往返。
l???????? 使用連接池以及根據模擬實際場景來調節性能。
l???????? 對非變化的數據使用并發來減輕數據庫鎖數據的花費。這可以避免鎖住數據庫行,以及因為鎖一直打開的數據庫連接。
l???????? 如果更新數據只需要很少的時間,而且數據容易被更改,那盡量避免使用并發。長時間的鎖越多,設計的可能性就越少。
l???????? 使用DataReader來執行順序的查找有助于提高性能。
?
安全考量
數據層必須保護數據庫免受偷竊或者破壞。同時也必須保護數據源可受訪問。
當設計安全策略時,考慮以下原則:
l???????? 當使用SqlServer時,考慮使用Windows驗證而不是SQL驗證。
l???????? 考慮到性能問題,避免中間層來扮演此角色。
l???????? 驗證所有穿越可信任邊界的數據。
l???????? 如果使用SQL語句,考慮使用參數方法來代替字符串拼湊以防止SQL注入。
l???????? 在配置文件里加密連接字符串以代替使用系統或DSN。
l???????? 加密敏感數據或使用數據庫加密來存儲密碼,使用Hash代替加密密碼版本。
l???????? 在網絡或Internet傳遞時,加密敏感數據。
l???????? 考慮在訪問數據源中實現最少權限。
l???????? 在數據層中要求調用者使用身份認證來審核。
l???????? 記錄登陸和身份認證信息。
?
部署考量
當部署數據訪問層,軟件架構師要考量生產環境中的性能和安全問題。
?
當部署數據訪問層時,考慮以下原則:
l???????? 把數據層和業務層放到同一個位置以提高程式性能。
l???????? 如果你要支持一個遠程的數據訪問層,考慮使用TCP協議來提高性能。
l???????? 你不能把數據訪問層和數據庫服務器放到一起。
?
模式映射
| Category | Patterns |
| General | ? Active Record ? Application Service ? Domain Model ? Layered Architecture ? Transaction Script ? Table Data Gateway ? Repository |
| Exception Management | ? Exception Shielding |
| Transactions | ? Master-Master Replication ? Coarse Grained Lock ? Capture Transaction Details ? Implicit Lock ? Optimistic Offline Lock ? Pessimistic Offline Lock ? Transaction Script |
?
重要模式
l???????? Active Record。 將數據訪問層放置域對象中。
l???????? Capture Transactions Details。創建數據庫對象,如觸發器和記錄表,來記錄變化。
l???????? Repository。封裝數據庫和持久化操作中的對象集。
l???????? Data Transfer Object。使用數據對象來減少調用方法的次數。
l???????? Table Data Gateway。讓sql統一訪問一個表或視圖來完成Select,Insert,Update和Delete操作。
?
技術考量
當選擇合適的數據層技術時,考慮以下原則:
l???????? 使用客戶端的數據庫訪問以提高性能。
l???????? 考慮使用企業庫模塊來簡化數據訪問代碼。
l???????? 使用System.Xml和其子命名空間來操作XML格式的數據。
l???????? 使用DataReader來呈現數據對基于asp.net的用戶接口比較有益,DataReader是一個只讀的,向前的讀寫器,讀取每一行的速度很快。
?
Additional Resources
For more information on data access performance, see the following resources:
? Architecture and Design Review of a .NET Application for Performance and Scalability
at http://msdn.microsoft.com/en-us/library/ms998544.aspx
? Design Guidelines for Application Performance at http://msdn.microsoft.com/enus/
library/ms998541.aspx
? Improving ADO.NET Performance at http://msdn.microsoft.com/enus/
library/ms998569.aspx
? Improving SQL Server Performance at http://msdn.microsoft.com/enus/
library/ms998577.aspx
? ADO.NET Scenarios - Optimistic Concurrency at http://msdn.microsoft.com/enus/
library/aa0416cz(VS.71).aspx
For more information on data access design patterns, see the following resources:
? Data Patterns at http://msdn.microsoft.com/en-us/library/ms998446.aspx.
? Enterprise Solution Patterns Using Microsoft .NET at http://msdn.microsoft.com/enus/
library/ms998469.aspx
For more information on general data access guidelines, see the following resources:
? .NET Data Access Architecture Guide at http://msdn.microsoft.com/enus/
library/ms978510.aspx
? Typing, storage, reading, and writing BLOBs at http://msdn.microsoft.com/enus/
library/ms978510.aspx#daag_handlingblobs
? Using stored procedures instead of SQL statements at http://msdn.microsoft.com/enus/
library/ms978510.aspx
? Sample ADO.NET scenarios
For more information on security, see the following resources:
? Architecture and Design Review for Security at http://msdn.microsoft.com/enus/
library/aa302421.aspx
? Design Guidelines for Secure Web Applications at http://msdn.microsoft.com/enus/
library/aa302420.aspx
轉載于:https://www.cnblogs.com/niujunjie1/archive/2008/11/27/1342538.html
總結
以上是生活随笔為你收集整理的PP团队圣经巨著《Application Architecture Guide2.0》14章-数据访问层的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 期待N年 天才级的全画幅CMOS终于要大
- 下一篇: 为量产FF91拼了!贾跃亭又找来6亿美元