前面的文章主要都是在圍繞關系資料庫理論進行研究,沒有涉及到資料庫系統的具體實作。雖說資料庫系統的具體實作因業務環境,RDBMS等因素而異,但總體開發流程,以及開發過程中所涉及到的一些問題,也具有不少統一的套路、标準。本文主要讨論資料庫系統實作過程中的重點環節、基本開發流程、資料庫管理以及資料品質工程等話題...
前言
前面的文章中,主要都是在圍繞關系資料庫理論進行研究,沒有涉及到資料庫系統的具體實作。
雖說資料庫系統的具體實作因業務環境,RDBMS等因素而異,但總體開發流程,以及開發過程中所涉及到的一些問題,也具有不少統一的套路、标準。
本文主要讨論資料庫系統實作過程中的重點環節、基本開發流程、資料庫管理以及資料品質工程等話題。
參照完整性限制對更新删除操作的影響
在第三篇(傳送門)中,我們已經讨論過,關系設計的目的就是為了減少備援消除更新異常。但當時也留下一個問題:外碼本身是備援的,那麼涉及到外碼的更新時怎麼辦呢?
關系資料庫理論将這個問題交給了RDBMS,讓它來解決涉及外碼的更新異常。下面先來看一下,涉及外碼的更新異常到底長什麼樣子。
在下面的這個關系中:
關系EMPLOYEE中的Dept屬性是一個外碼,它對應DEPARTMENT關系的主碼。如果對該屬性進行更新或者删除,那麼這個外碼就找不到它對應的主碼,兩個關系的聯系就被破壞了。針對這個問題,RDBMS的解決方案有四個,下面以删除異常為例進行說明:
1. 限制删除
限制删除是指如果某記錄主碼被另一個記錄外碼對應,則該記錄不允許被删除。如上面示例DEPARTMENT關系中的記錄在删除的時候有可能被RDBMS禁止。
2. 級聯删除
級聯删除是指如果某個記錄的主碼被另一個記錄的外碼對應,那麼這兩個記錄将一起被删除。
3. 設定為空
是指如果某個記錄的主碼被另一個記錄的外碼對應,那麼在删除這個記錄後,另外那個記錄的外碼字段置為空。
4. 設定預設值
同3,不過是将置為空改為設定成一個預設值。
更新情況和删除一樣,要注意的是所有處理都發生在對外碼映射中的非外碼關系進行操作時發生。這些處理主要是對外碼關系進行附加操作,如級聯删除,置空,置預設值,或者報錯。
索引機制
索引(index)機制的本質是一種檢索加速機制,本文将從索引的邏輯意義上對它進行解析,至于其在各RDBMS裡的實體實作細節則不做介紹。事實上若非資料庫維護管理人員,也沒必要知道。在下面這張客戶關系表中:
id是按順序排列的,是以如果要檢索某id對應記錄,則由于記錄已按id排好序,可使用多種查找算法提高檢索效率,如二分查找等。但關系中某一列排好序以後,其他列必然是亂序的,那怎麼辦?在RDBMS中,這種情況可以通過建立一個隻包含兩列的附加表來實作:
索引表中其中一列為索引字段,另一列則包含一個指針指向原紀錄。這樣在對索引列進行查詢的時候,RDBMS會先對索引表進行操作,完了再映射到原表并傳回結果。
從本質上來說,這是一種犧牲空間換取時間的辦法,索引建立不單耗費存儲資源,而且會降低更新、删除等操作的效率。是以不是說建的索引越多就越好,具體建立何種索引,建立多少索引,則要取決于計算資源,RDBMS,業務場景等因素。
觸發器機制
觸發器是一種規則,當關系中删除、插入、修改一條記錄的時候執行。它的應用場景很多,故幾乎所有RDBMS都提供了該功能。如下代碼是在MYSQL中編寫的觸發器,它施加于student關系的insert操作上:每次insert一條學生記錄後,都會更新關系中的記錄數,如果記錄數超過10,則不為新的學生配置設定導師:
CREATE TRIGER studentinserttrigger
BEFORE INSERT ON student
FOR EACH ROW
BEGIN
DECLARE totaladvised INT DEFAULT 0;
SELECT COUNT(*) INTO totaladvised
FROM student
WHERE advisorid = NEW.advisorid;
IF (totaladvised >= 10) THEN
SET NEW.advisorid = NULL;
END IF
END;
注意這段代碼不是标準SQL代碼,不必細究。觸發器實作代碼的文法規則取決于RDBMS,需要時再有針對性的參考手冊即可。
資料庫系統開發流程
所謂資料庫系統(database system),就是指讓使用者和資料庫資訊之間進行有效互動的計算機系統。其典型的架構如下圖所示:
可見, 資料庫系統的三大主要成分分别是:資料庫,資料庫管理軟體RDBMS,還有前端應用程式(網站,APP等)。資料庫是資料庫系統的核心,負責存放所有資料。而資料庫對外的所有互動,均通過RDBMS來進行。一般使用者通過前端應用程式使用RDBMS,而比較專業的使用者也可直接使用RDBMS操縱資料庫。
舉例來說,某人通過APP訂購商品,那麼這個APP就是前端應用程式。而當他有一個具體行為,比如付款的時候,前段應用程式就會和RDBMS通信,讓RDBMS完成扣款并傳回操作執行結果。
資料庫系統的總體開發流程,可以總體劃分為以下步驟:
1. 資料庫需求
需求搜集是所有環節中最重要的一步,吃透了使用者需求,往往就成功了大半。這些需求将指導後面如需求模組化、實作、以及前端應用程式開發等。通常來說,需求都會通過ER圖來表示(參考本系列第一篇),并和各業務方讨論搜集得到,最終整理成文檔。
要特别強調的一點是資料庫系統開發需求階段過程是循環疊代式的,一開始的需求集并不大,但随着項目的進展,需求會越來越多。而且不論是以上哪個階段發生了需求變動,整個流程都需要重新走一遍,決不允許隐式變更需求。
2. 資料庫模組化
也就是邏輯模型模組化,在本系列第二篇有過詳細講解,這裡不再贅述。
3. 資料庫實作
這一步的本質就是在空的RDBMS裡實作2中建立的關系模型,一般通過使用SQL或者RDBMS提供的前端工具實作。
4. 開發前端應用程式
前端應用開發在需求搜集好了之後就開始進行,主要有網站、APP等前端形式。另外前端程式的實際實作涉及到和資料庫之間互動,是以這一步的最終完成在資料庫模組化之後。
5. 資料庫部署
顧名思義,這一步就是部署資料庫系統的軟硬體環境。筆者這裡插一個故事,以前在A公司工作時,一哥們自告奮勇到某政府秘密部門部署私有雲環境。那地方很偏僻,不允許外網,U盤都不能用,隻能CD光牒安裝。而A公司的雲平台部署是一件非常複雜的活,于是那哥們就在那裡呆了一個多月,回來後據說是瘦了7斤......
回到正題,資料庫部署往往還包含将初始資料填入資料庫中的意思。對于雲資料倉庫,這一步就叫"資料上雲"。
6. 資料庫使用
這一步沒啥多講的,就再講一個有關的故事吧。同樣是在A公司,有一次某政企私有雲項目完成後,我們有人被派去給他們教育訓練如何使用。結果去的人回來後說政企意見很大,認為讓他們學習SQL以外的東西都不行。拒絕用Python寫UDF,更拒絕MR程式設計接口,隻要SQL和圖形界面操作方式。一開始我對政企的這種行為有點看不起,但後來我想,就是因為有這群挑剔的使用者,才使得A公司雲産品的易用性如此強大,進而占領國内雲計算的大部分市場。使用者的需求才是技術的唯一試金石。
7. 資料庫管理和維護
嚴格來講,這部分不算開發流程,屬于資料庫系統開發完成後的工作。接下來本文将圍繞這個話題進行講解。
資料庫系統管理
資料庫系統發行後,控制權便從資料庫設計、實作、部署的團隊移交給了資料庫管理者(database administrator, DBA),并由他們來對系統進行管理。
資料庫管理涵蓋了確定一個已經部署的資料庫系統正确運作的各種行為。為了實作這一目标,資料庫管理具體包含以下範疇:
這部分工作的涉及面相當廣而深,應由專業的DBA團隊去完成。本文主要針對人群是資料科學家,是以僅對這些工作做一個簡明的介紹。
1. 資料庫系統監測與維護
監測工作可以讓DBA掌握資料庫系統的運作情況,并針對發現的問題進行維護。比如發現存儲資源不夠用了,則要配置設定給資料庫系統更多存儲空間等。
同時,監測工作也可以讓DBA知道關系資料庫中各關系的具體使用情況,進而進行優化。比如某兩個表被大群使用者頻繁使用,并隻用來重複建立相同的報表。這時候DBA就可以考慮建議資料庫開發團隊反規範化設計的将這兩個表合并到一起。
維護工作是指DBA在監測到了問題後,采取的修複行為。比如上面提到的配置設定更多存儲空間,向資料系統加入新的關系(注: 資料庫開發設計人員決定是否加入關系,DBA負責建議加入和具體執行),都屬于維護範疇。
2. 資料庫安全保障
資料庫安全保障工作可以說是資料庫系統管理工作中的首要任務,該任務需要DBA對資料的存取過程嚴加控制。
具體點來說,就是要求DBA做好資料庫通路人員的認證工作,并對所有使用者進行權限劃分。
此外,對于特别敏感的資料,還應進行加密處理。這部分功能一些商業資料庫做得很好,比如Oracle。
3. 資料庫備份與恢複
這裡簡要說明一下資料庫備份與恢複的原理。我們知道,資料庫的資料,是存放到磁盤裡的。而計算機對資料的處理過程,都是先把資料從硬碟轉移到記憶體,處理完後再放回去。
而如果資料在記憶體中進行處理,還沒有将資料轉移回磁盤的時候,資料庫挂了的話就将導緻資料丢失。是以RDBMS采用恢複日志(recovery log)機制,先記錄更新操作要做的事情,比如那個資料被更新,更新前後的值,更新請求的使用者等,然後再做具體的更新操作。在更新日志中可以設定"檢查點",之後DBA可使用它進行周期性副本備份。失效事件發生之後,DBA可以利用"檢查點"進行系統恢複:復原(Roll Back)至指定檢查點狀态。
對于那種徹底性毀壞的情況,比如發生火災、地震等,可在多個不同實體站點上保留完全鏡像備份(complete mirrored backup)。這些副本需持續更新保證與資料庫系統一緻。
4. 資料庫性能優化
性能優化工作包括設定索引,逆規範化,SQL優化等等。通常有QPS(query per second)等名額來衡量資料庫系統的優化效果。
這部分工作内容很多也比較雜,主要通過DBA管理RDBMS的查詢優化器完成。但對于資料庫的開發員和使用者來說,也多多少少要知道一點,比如寫Hive語句的時候需要靈活設定分區,避免資料傾斜等。這些具體環境的優化方案,本文篇幅有限就不一一講解了。
5. 資料庫标準制定
這部分工作包括資料庫中字段命名規範,SQL編碼規範的制定等。除了這些開發标準,還有使用标準,比如使用資料庫的人需要遵守哪些有益于資料庫系統健康的行為規範。
資料品質體系
資料庫系統,以及接下一個系列要講的資料倉庫系統,都需要始終重視資料品質問題。用一句話概括,資料品質就是衡量資料能否真實、及時反映客觀世界的名額。
具體來說,資料品質包含以下幾大名額:
1. 準确性
準确性要求資料能夠正确描述客觀世界。比如某使用者姓名拼音mu chen錯誤的錄入成了muc hen,就應該彈出警告語;
2. 唯一性
唯一性要求資料不能被重複錄入,或者不能有兩個幾乎相同的關系。比如張三李四在不同業務環境下分别建立了近乎相同的關系,這時應将這兩個關系合并;
3. 完整性
完整性要求進行資料搜集時,需求資料的被描述程度要高。比如一個使用者的購買記錄中,必然要有支付金額這個屬性;
4. 一緻性
一緻性要求不同關系、或者同一關系不同字段的資料意義不發生沖突。比如某關系中昨天存貨量字段+當天進貨量字段-當天銷售量字段不等于當天存活量,否則就可能是資料品質有問題;
5. 及時性
及時性要求資料庫系統中的資料"保鮮"。比如當天的購買記錄當天就要入庫;
6. 統一性
統一性要求資料格式統一。比如nike這個品牌,不能有的字段描述為"耐克",而有的字段又是"奈克";
資料品質和資料具體意義有很大相關性,是以無法單憑資料庫理論來保證。且由于具體業務及真實世界的複雜性,資料品質問題必然會存在,不可能完全預防得了。是以很多RDBMS或第三方公司都提供了資料品質工程服務/軟體,用來識别和校正資料庫系統中的各種資料品質問題。
小結
本篇作為資料庫系列的終篇,主要圍繞資料庫系統實作所涉及到的方方面面進行講解。想必讀者看完本文後會和我一樣,感受到一個完整而優秀的資料庫系統實作并不簡單,甚至可以說是比較繁瑣。雖說實際項目中每個人隻需要專門負責其中一個或者幾個子產品,不過筆者認為作為一名優秀的資料庫開發人員,也必須對全局有一定的認識,這也是本文意義所在。
最後談點題外話吧。筆者本人是一名資料挖掘工程師,看到很多朋友把精力完全投到研究資料挖掘算法和實作上,私以為這樣做是很不科學的。因為一個優秀的資料挖掘引擎,必然架構在一個優秀的資料庫/資料倉庫系統之上。而一個資料挖掘工程師80%的工作都是在利用這些系統進行資料清洗、特征提取等,深入思考算法模型的時間并不多(除非您是在特别牛的平台性算法團隊工作)。是以在深入學習資料挖掘算法之前,一定要有良好的資料基礎知識,不能好高骛遠。
下個系列的主題是資料倉庫,它和本系列,以及另幾個系列,如"資料可視化_R語言","資料分析_Excel"一樣都是資料基礎知識的重要組成部分。期待各位讀者的持續關注、交流、指正。