關系型到文檔型的跨越
在文檔型NoSQL數據庫出現之前,許多開發者一直絞盡腦汁思考,希望能想出更好的處理關系型數據庫技術的方法,如今他們可能要跳出那種思維而另辟蹊徑。本篇將介紹關系型數據庫和分布式文檔型數據庫的區別以及在應用開發上的一些建議。
1. 為什么要轉變?
人們通常都不愿意改變,因為改變總是痛苦的,除非它能顯著解決一些問題。隨著大數據的發展,我們越來越有必要開始對數據模型做出轉變了。換句話說,這種轉變的需求愈發的強烈,因為大數據時代不管是對于數據庫的擴展模型還是數據模型都要求極高的靈活性。
1.1 擴展模型
關系型數據庫是一種“縱向擴展”的技術,想要擴展容量(無論數據存儲還是I/O),都需要更換更大的服務器。現代應用結構的解決卻是使用“橫向擴 展”----無需新購買更大的服務器,只需要在負載均衡器下增加一般的服務器、虛擬機或是云服務器就可以實現擴展。此外,容量在不再需要的時候還可以輕易 的縮減。事實上,“橫向擴展”在應用邏輯層的使用已經很廣泛了,只是數據庫技術上剛剛趕上而已。
1.2數據模型
NoSQL“橫向擴展”部署方案的優點已經受到了業界的注意,但是同時很多人忽略的是NoSQL數據管理的簡潔,不需要很復雜的操作模式構建,這 一點對于數據庫的提升也和擴展模型一樣重要。在使用傳統關系數據庫時,添加數據前,需要定義操作模式。之后每一條記錄的加入都需要嚴格的按照定義的操作模 式進行,比如固定的列數和數據類型。因此,改變那些分區關系型數據庫的操作模式,會非常的麻煩。如果你的數據獲取和數據管理需求經常變化,那這種嚴格的模 式限制將會成為制約表現的屏障。
NoSQL(無論文檔型、列式、K-V等等)都是水平擴展的,它們都不需要預先定義操作模式、所以也不需要在需求改變時改變操作模式。
接下來我就將使用SequoiaDB來介紹文檔型NoSQL數據庫技術:
2. 數據模型:關系型vs.文檔型
下圖就對比了四條記錄在關系型和文檔型數據模型下的存儲情況:
2.1 關系型數據模型
如上所示,關系型數據庫中的每一條記錄存儲都需要遵守一個固定的模式----固定的列數,每一列都是有特定的意義而且規定了數據類型。如果要獲取不同的數據,數據庫的模式就需要重新修改。
此外,關系型模型還有一個特點就是“數據庫標準化”,也就是大的表會被壓縮成小的、整合的表,如下圖所示:
在上面的例子中,數據庫用來存儲錯誤日志信息。每個錯誤記錄(表1中的一行)由3部分組成:錯誤號ERR,錯誤發生的時間TIME,和錯誤發生的 數據中心DC。為了避免重復記錄所有的錯誤記錄的數據中心信息,現在每條錯誤記錄將都指向表2(數據中心信息)中的對應的地點那一條記錄。這樣就不需要實 際存儲具體的DC信息在表1中,需要使用時只要到對應的表2行獲取就可以了。
在關系模型當中,多個表中的不同記錄經常“交錯連接”,一些數據會被多條記錄共享。這樣的好處就是減少了重復數據的出現,但是這樣不好的地方就是 一旦其中某一條鏈接的記錄發生改變,那么與其相關的記錄和表都會被鎖住以防止非一致性的出現。 ACID事務在關系型數據庫中是很復雜的,因為數據會擴散。即便是單一條記錄,這復雜的共享數據內部關系網的存在,也使得關系型數據在多個服務器之間的傳 遞變得復雜而緩慢,同時讓讀和寫操作的性能變差。
當存儲空間昂貴又稀少時,折中的權衡方案是很必要的。然而,如今存儲空間的價格跟40年前相比已經大大的下降了,很多時候計算折中方案已經完全沒有必要。使用更多的存儲空間來換取更好的操作性能,或者是將工作負載分配到多臺機器上,這才是如今應用上更好的解決方案。
2.2文檔型數據模型
使用“文檔”這個詞似乎讓人覺得奇怪,但是其實 “文檔型數據模型”真的和傳統意義的文字“文檔”沒有什么關系。他不是書、信或者文章,這里說的“文檔”其實是一個數據記錄,這個記錄能夠對包含的數據類 型和內容進行“自我描述”。XML文檔、HTML文檔和JSON 文檔就屬于這一類。SequoiaDB就是使用JSON格式的文檔型的數據庫,它的存儲的數據是這樣的:
{ “ID”:1, “NAME”: “SequoiaDB”, “Tel”: { “Office”: “123123”, “Mobile”: “132132132” } “Addr”: “China,GZ” }
可以看到,數據是不規則的,每一條記錄包含了所有的有關“SequoiaDB”的信息而沒有任何外部的引用,這條記錄就是“自包含”的。這就使得 記錄很容易完全移動到其他服務器,因為這條記錄的所有信息都包含在里面了,不需要考慮還有信息在別的表沒有一起遷移走。同時,因為在移動過程中,只有被移 動的那一條記錄(文檔)需要操作而不像關系型中每個有聯系的表都需要鎖住來保證一致性,這樣一來ACID的保證就會變得更快速,讀寫的速度也會有很大的提 升。
3. 文檔型數據模型的應用
你可能需要一段時間去忘記以前的習慣,不過不要害怕,了解其他方面的知識可以讓你更充分的利用你已經學會的知識,不管怎么樣最能解決問題的才是最好的。了解了不同的方法,你才可以選擇最適合的!
3.1 模型
在應用中,數據對象是核心的部分-----也是模型視圖控制器(MVC)中的模型層。當分析一款應用時,現在你可以先把目光停在對象關系映射層 (ORM)上。與其將不同的模型定制成為不同的表和行,不如都用JSON格式存儲成文檔形式吧,每個JSON文檔都有唯一的id方便查找。
3.2 鍵
在文檔型數據庫中,每個JSON文檔的ID就是它唯一的鍵,這也大致相當于關系型數據庫中的主鍵。通常ID在一個數據庫“集合”中是唯一的 (NoSQL中,類似RDBMS的“表”的分類結構有很多種,如SequoiaDB的集合Collection或者是Couchbase的 bucket)。
一些NoSQL數據庫會用ID排序,那么相近ID的數據自然更容易被檢索到,經常需要一起調用的數據放在一起可以大大提升處理的速度。
3.3 靈活性
如今的社交網站越來越普及,而隨著用戶量不斷壯大,每個用戶的使用方式或者是發布的內容類型都不盡相同。有人會發布風景照片、有人發布對時事的評 論還有人分享音樂表達心情。面對如此大量而多樣性的數據,如果使用關系型模型,就需要不斷你的修改數據操作模式,這樣,可能會引起系統負載的大大提升,同 時也會大大增加處理的時間。
這時,文檔型模型存儲就凸顯其優點了,面對復雜多變的數據,使用文檔型模型就直接保留了原有數據的樣貌,不需要另外創建新的表新的操作模式來處 理,這樣不僅存儲直接快速,再過后調用時,也可以做到“整存整取”,不需要關系型模型那樣再到各種鏈接的表上取出需要顯示的記錄。在RDBMS中,需要盡 可能的標準化數據。而在NoSQL中,則是可以盡可能的對數據“去標準化”。
3.4 并發性
接著上一個例子,在社交網絡當中,用戶的操作量很大,許多人每天會花很多的時間泡在社交網絡之中。使用傳統關系數據模型時,例如,兩個用戶的發布 信息同時鏈接到了“地點”,那么其中一個人回頭修改自己的發布時,因為鏈接到了“地點”表,系統為了保證一致性就會把“地點”表鎖住不讓其他用戶同時提出 修改,這時另外的用戶暫時就沒辦法操作“地點”表了。
如果使用文檔型模型,每個人的發布就是獨立的一個“文檔”,這一個文檔文件就包含了這一條發布的所有信息。因為這種“自包含”的特性,不同的用戶修改數據只需要修改自己的文檔而不會影響別人的操作。這樣就實現了高的并發性!
4. 結論
關系型數據模型的復雜查詢操作,倚賴的是數據庫模式的嚴格一致,數據的標準化以及數據的合并。在過去的40年中,關系型模型和查詢技術已經發展成熟也被眾多的開發者所熟悉。
但是,應用、用戶和基礎的特點的變化使得應用開發者和架構師開始選擇“NoSQL”這種非關系型的數據庫技術,許多觀點認為分布式文檔數據庫技術在很多方面都要勝過RDBMS:
- 它可以輕松的通過普通機器、虛擬機或者云實例來實現近乎無上限的水平擴展。
- 添加數據是他不需要嚴格的數據庫操作模式,因此在修改數據類型時自然也不需要修改數據庫模式。
- 多樣化的數據模型能更好的的支持復雜數據的建模、存儲和查詢。
雖然,數據的去結構化可能會使用到更多的空間,但隨著存儲空間價格的不斷下降,存儲空間和讀寫速度的比重勢必將越來越像追求速度一方傾斜,而由此帶來的高性能、可擴展性以及靈活的數據結構等優點又將大大提升應用的各方面性能表現。
SequoiaDB的數據模型就是以JSON格式存儲的文檔型模型,所以SequoiaDB具備了文檔型和NoSQL數據庫的數據靈活性和高可擴 展性。SequoiaDB的文檔型數據模型不僅簡化了數據存取的過程,也大大的提升了數據的靈活性。在應用中不僅免去了設計模式這個麻煩的環節,還能很好 的適應大數據時代高并發、實時性和分布式的要求。
作者簡介: 李方舟(Ark),目前在國產開源新型分布式數據庫公司工作,大數據行業的新行者,喜歡研究開源,關注行業動態。