DBHub的前世今生

xiangcns發表於2021-01-01

1 為什麼會做這個元件

我們開發材料管理系統的時候,有大量的增刪改查操作場景,特別是對材料明細量表進行操作的時候,我們遇到了一些問題:

  1. 如果使用者每輸入一行資訊就執行一次資料庫讀寫的話,古老的ADO.NET元件執行效率不高;
  2. 資料庫連線反覆開關,而且在多使用者併發操作的情況下表出現鎖衝突;
  3. SQL語句拼接工作量大,完全屬於無技術含量的體力勞動;

做這個元件的最主要初衷並不是打算對效能進行革命性的提升,因為用的還是ADO.NET,我最主要的想法是為了偷懶,把拼接sql語句的工作封裝起來,用一個標準化的方法來解析和組裝sql語句,並直接執行返回結果,我的目標是:

  1. 所有的增刪改都不再需要寫SQL語句;
  2. 所有的資料批量增刪改操作在一次資料庫連線開啟關閉內完成;

那個時候.NET雖然有ORM元件,但是在資料批量處理時能力弱,一衝動就自己造了個輪子。

2 元件的設計思路

DBHub的作用是為了方便地將資料集(以下簡稱dt)批量寫入或更新到資料表,這個寫入一般就是單純的insert操作,更新則包括了兩個含義,一是資料記錄的某些非主鍵欄位值發生了變化,這個是update操作,二是資料記錄被刪除了,這個是delete操作。現在就要解決一個問題,我們如果用最方便的方式告訴系統所有這些操作的內容。

2.1 下面先定義兩個概念:

  1. 目標資料集dt:資料庫表原始內容或者原始內容的子集完成全部操作後的資料集;
  2. 參照系資料集ds:資料庫表原始內容或者原始內容的子集;

2.2 使用者要做的事情是:

  1. 把資料集按照表結構組裝起來,並在記憶體中處理成目標資料集dt;
  2. 查詢出參照系資料集ds;
  3. 把dt和ds交給DBHub,剩下的事情由DBHub全部搞定(讓它幫我們把ds變成dt)。

2.3 設計圖

在這裡插入圖片描述

2.4 設計思路:

DBHub的核心思想就是把對SQL的拼接處理改成對DataTable物件的處理,有一點ORM的思想在裡面,畢竟DataTable物件也可以理解為就是一個Dto物件,我們根據業務邏輯把dt加工好,使得dt變成最終成品的樣子,然後去資料庫裡取參照系資料集ds,這個ds可能是整張表,也可能是整張表的子集,DBHub負責封裝標準的方法,將ds加工成dt的樣子。

為什麼需要ds的子集,因為ds有可能非常大,DBHub對dt進行加工的時候必不可少需要對參照系ds進行遍歷和取值,如果ds超級大,那遍歷的速度可想而知,這也就是為什麼要設計一個filter引數的原因。

早期.NET的ORM處理批量資料的效能不理想,有一些第三方的資料持久層框架,但是用起來好複雜,於是我下決心自己造了這個土輪子,現在ORM效能已經越來越好,不過DBHub在一些特定場景(同時存在插入、修改和刪除操作的大批量資料)表現依然穩定,而且使用Bulk方法,所以資料寫入速度非常快(號稱百萬行資料秒級寫入)。

2.5 功能和特性:

  1. 將所有對資料表的增刪改操作通過對dt的處理一次性更新到資料表;
  2. 對主鍵已經存在的資料可以通過引數開關決定是採用略過或者更新的方式來處理;
  3. 可以通過過濾器引數,縮小參照系資料集ds,提升DBHub成員方法內部資料處理的效能;
  4. 判斷送入的dt與資料表結構是否一致,提示缺少的欄位或者多出的欄位;
  5. 支援多個欄位是主鍵;
  6. 判斷主鍵是否一致;

3 規劃

未來我想實現對多種主流關係型資料庫的適配,使DBHub成為一個通用型元件,但是難度還是非常大的,基本上需要完全重寫。前路漫漫,願我們歸來仍是少年。

相關文章