技術丨淺談如何設計數據讀取框架簡化資料庫操作

本文作者:lcl,來自於太閣社區TigerX。

最近接到任務,設計一個專門用於鏈接特定資料庫的interface,利用python對接資料庫數據並進行機器學習(資料庫使用Mongodb, python版本是3.5)。鑒於用戶為工程師而非程序員,對python編程語言僅僅有基本的了解,所以把interface設計的簡單,易懂,高效無錯,就成為衡量項目完成質量的重要標準。

很高興有機會分享在完成設計的過程中遇到的幾個問題,

1. 什麼是mongodb,如何在python上初始化mongodb資料庫鏈接

2. 大數據查詢過程中,如果不做任何簡化任由系統一一揀選,則耗時費力。以本項目為例,未經優化前讀取10萬條數據需時四分鐘,等待的時間太長。如何限制數據遍歷量,加快數據讀取速度

3. 如何處理返回值,進行封裝保存

另外還有一些問題可能在實際處理中會遇到,也列出來供大家參考 :

a. 數據在傳輸過程中可能出現異常,致使資料庫導入時報錯(例如Null值或不識別字元)。如何進行數據預處理以降低系統故障概率甚至避免系統崩潰是需要考慮的一個方面。

b. 如何檢查提取的二進位數據是否有效,是否能嘗試代碼復用。

0.為什麼要設計一個interface

就完成單一任務來說,直接coding往往是功效最快的。既如此,為何要強調設計interface?這裡就不得不提到面向介面的設計思想。一般來說,在面向對象的系統中,系統的各種功能是由不同對象協作完成的。在這種情況下,各個對象內部是如何實現對系統設計人員來講就不那麼重要 了;而各個對象之間的協作關係則成為系統設計的「關鍵」。正因為系統性,直接編程往往會忽視全局,反而招致返工。

如何理解這種「關鍵」?就比如客戶端資料庫登陸,直接獲取用戶名密碼即可,便實現了該模塊功能,然而從交互角度,我們仍需驗證用戶名是否非法(與伺服器端交互),和密碼是否匹配(安全模塊交互)等等功能,確保各方法相互協調。

然而此類設計無法一蹴而就,往往對功能的設計探本溯源便是對細節的步步落實。下面便根據遇到的問題,逐步探索實現這個介面遇到的問題。為了照顧不太熟悉mongodb的同學,在開始先簡要介紹mongodb。

1. mongodb 簡介

MongoDB 是一個基於分散式文件存儲的資料庫,本身是一個介於關係資料庫和非關係資料庫之間的產品。支持的數據結構非常鬆散,是類似json的bson格式,因此可以存儲比較複雜的數據類型。Mongodb最大的特點是支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能,而且還支持對數據建立索引。

Mongodb自身兼有對複雜數據類型(比如json)的支持,不像mysql的固定數據結構那樣死板,與此同時,查詢語句句法多樣,快捷高效,此外支持索引以加速數據查詢。同時,mongodb可以下載免費版,節省資金。上述種種自然而然使其成為了即時數據存儲的最佳選擇(比如爬蟲爬的的文本資源)。

2. 項目預處理

首先是對json格式數據的處理。mongodb支持json格式,並且大部分數據使用json,如何將json進行格式轉化,如何對其中數據分類存儲,如果提取到二進位編碼是否需要考慮編碼,這些都是具體實現的時候可能需要分析的細節。

可以考慮使用python的pickle庫做相應處理(例如pickle.load()和pickle.dump()),只要數據完整無錯,命令不會複雜。相關命令可搜索pickle庫。

json格式數據

其次是如何加速大數據下的排序與查找,如問題二所示。方法是建立多索引對資料庫優化。下文會討論具體流程。

本項目涉及的索引(index):

3. 項目實現

首先建立資料庫與python的鏈接,確保數據可以從資料庫中讀出,之後建立索引加速查詢,然後做數據清洗,轉化為用戶需要的格式並封裝結果存入文件或存為numpy array。最後,使用資料庫返回的cursor進行符合要求的query,返回數據集,封裝為pandas.dataframe形式返回給用戶,同時使用pd.to_csv自動寫入csv文件(此處使用tsv文件應是更佳,因為可能數據中存在逗號,使用csv對數據二次使用有不利影響,不利於數據處理,例如split)留存用戶備份。

1.建立資料庫與python的鏈接。

首先需要下載pymongo,一種mongodb為在python運行提供的library。之後import mongoClient,用client建立資料庫與python的直接連接。

在此過程中仍舊需要處理以下參數:

hostname: 主機名,默認參數是 localhost,如果mongodb是部署在集群伺服器,採用主從式分布,hostname應根據具體情況填寫

port :埠號,默認參數是本地埠27017,多伺服器下埠號應根據具體情況填寫

db: 導出數據的資料庫的名稱

collection:導出數據的具體集合的名稱

開始階段照例進行初始化

鑒於 hostname,port這兩個參數是數據導出的起點,地位重要且都應作為變數,最終我寫了preDB函數來實現對其參數的記錄和出現異常後的故障處理。

之後便是訪問資料庫,也就是使用從用戶處得到的db,colection建立數據訪問許可權,最後是索引的建立。索引的建立取決於具體資料庫的數據結構,不同情況下primary key不同,結果也大不一樣。這裡取時間(timestamp)做關鍵字。

建造索引需要使用create_index命令

XX=create_index([key,mode=ASCENDING]) mode預設為降序排列

下面看一下使用索引後數據讀取情況:

使用索引之前:

使用索引之後:

索引的一大好處是可以加速數據輸出速度。另外,索引的建立基於資料庫,一旦執行一次,便永久生效,不需重複執行命令。

dataext object可以利用cursor的返回值進行數據加工,以獲得需要的滿意結果。

cursor的作用相當於指針,在query結束後引導數據返回數據加工模塊。上文提到的存儲和封裝便可以藉助cursor實現。比如如下code:

定義了dataExtrc class,使用dataExtrc object來接收從cursor中返回的符合要求的documents並進行存檔和封裝。

以上便是用python設計一個方便mongodb數據傳輸的簡易框架的過程。使用這個框架,便不需要頻繁的啟動mongodb伺服器,在命令行中敲打大量重複代碼了。

歡迎大家來我的github上圍觀這個項目,url: github.com/Cli98/databa

更多矽谷第一手科技資訊,歡迎關注公眾號「論碼農的自我修養」或搜索「bit_tiger」。


推薦閱讀:

【乾貨合集】Redis深入之道——Redis4.0、讀寫分離技術揭秘及實戰應用
分散式架構系統生成全局唯一序列號的一個思路
IMVC(同構 MVC)的前端實踐
基於TableStore構建簡易海量Topic消息隊列
CODING 代碼託管架構升級之路

TAG:数据库 | 架构 | 后端技术 |