NOSQL介紹


一、NQSQL概述

1.1 什么是NOSQL

首先需要說的是,NoSql並不表示NO SQL"沒有SQL"的意思。實際上,它是"Not Only SQL"的縮寫。它的意義是適用關系型數據庫的時候就使用關系型數據庫,不適用的時候也沒有必要非使用關系型數據庫不可,可以考慮使用更加合適的數據存儲。為彌補關系型數據庫的不足,各種各樣的NoSQL數據庫應運而生。

1.2數據庫分類

數據庫根據不同的數據模型數據的表現形式)主要分成階層型網絡型關系型3種。

(1) 階層型數據庫

早期的數據庫稱為階層型數據庫數據的關系都是以簡單的樹形結構來定義的。程序也通過樹形結構對數據進行訪問。這種結構,父記錄(上層的記錄)同時擁有多個子記錄(下層記錄),子記錄只有唯一的父記錄。正因為如此,這種非常簡單的構造在碰到復雜數據的時候往往會造成數據的重復(同一數據在數據庫內重復出現),出現數據冗余的問題。階層型數據庫如下圖所示:

階層型數據庫把數據通過階層結構的方式表現出來,雖然這樣的結構有利於提高查詢效率,但與此相對應的是,不理解數據結構就無法進行高效的查詢。當然,在階層結構發生變更的時候,程序也需要進行相應的變更。

(2) 網絡型數據庫

前所述,階層型數據庫會帶來數據重復的問題。為了解決這個問題,就出現了網絡型數據庫。它擁有同階層型數據庫相近的數據結構,同時各種數據又如同網狀交織在一起,因此而得名。階層型數據庫只能通過父子關系來表現數據之間的關系。針對這一不足,網絡型數據庫可以使子記錄同時擁有多個父記錄,從而解決了數據冗余的問題。下圖所示為網絡型數據庫。

但是,在網絡型數據庫中,數據間比較復雜的網絡關系使得數據結構的更新變得比較困難。另外,與階層型數據庫一樣,網絡型數據庫對數據結構有很強的依賴性,不理解數據結構就無法進行相應的數據訪問。

(3) 關系型數據庫

最后要向大家介紹的是以科德提出的關系數據模型為基礎的關系型數據庫。關系型數據庫把所有的數據都通過二元表現形式表示出來,給人更容易理解的直觀感受。網絡型數據庫存在着數據結構變更困難的問而關系型數據庫可以使多條數據根據值來進行關,這樣就使數據可以獨立存在,使得數據結構的變更變得簡單易行。對於階層型數據庫和網絡型數據庫,如果不理解相應的數據結構,就無法對數據進行讀取,它們對數據結構的依賴性很強。因此,它們往往需要專業的工程師使用特定的計算機程序進行操作處理。相反,關系型數據庫將作為操作對象的數據和操作方法(數據之間的關聯)分離開來,消除了對數據結構的依賴性,讓數據和程序的分離成為可能。這使得數據庫可以廣泛應用於各個不同領域,進一步擴大了數據庫的應用范圍。

1.3 關系型數據庫優勢

(1) 通用性及高性能

關系型數據庫的性能絕對不低,它具有非常好的通用性和非常高的性能"。毫無疑問,對於絕大多數的應用來說它都是最有效的解決方案。

(2) 突出的優勢

關系型數據庫作為應用廣泛的通用型數據庫,它的突出優勢主要有以下幾點:

保持數據的一致性(事務處理)

由於以標准化為前提,數據更新的開銷很小(相同的字段基本上都只有一處)

可以進行JOIN等復雜查詢

存在很多實際成果和專業技術信息(成熟的技術)

這其中,能夠保持數據的一致性關系型數據庫的最大優勢。在需要嚴格保證數據一致性處理完整性的情況下,用關系型數據庫是肯定沒有錯的。但是有些情況不需要JOIN,對上述關系型數據庫的優點也沒有什么特別需要,這時似乎也就沒有必要拘泥於關系型數據庫了。

1.4 關系型數據庫的不足

(1) 不擅長的處理

就像之前提到的那樣,關系型數據庫的性能非常高。但是它畢竟是一個通用型的數據庫,並不能完全適應所有的用途。具體來說它並不擅長以下處理:

大量數據的寫入處理

為有數據更新的表做索引表結構(schema)變更

字段不固定時應用

對簡單查詢需要快速返回結果的處理

下面逐一進行詳細的說明。

(2) 大量數據的寫入處理

在數據讀入方面,由復制產生的主從模式(數據的寫入由主數據庫負責,數據的讀入由從數據庫負責),可以比較簡單地通過增加從數據庫來實現規模化。但是,在數據的寫入方面卻完全沒有簡單的方法來解決規模化問題,讀寫集中在一個數據庫上讓數據庫不堪重負,大部分網站開始使用主從復制技術來實現讀寫分離,以提高讀寫性能讀庫的可擴展性Mysqlmaster-slave模式成為了這個時候的網站標配。

例如,要想將數據的寫入規模化,可以考慮把主數據庫從一台增加到兩台,作為互相關聯復制的二元主數據庫來使用。確實這樣似乎可以把每台主數據庫的負荷減少一半,但是更新處理會發生沖突(同樣的數據在兩台服務器同時更新成其他值),可能會造成數據的不一致。為了避免這樣的問題,就需要把對每個表的請求分別分配給合適的主數據庫來處理,這就不那么簡單了。下圖所示為兩台主機問題和二元主數據庫問題的解決辦法。

另外也可以考慮把數據庫分割開來,分別放在不同的數據庫服務器上,比如將這個表放在這個數據庫服務器上,那個表放在那個數據庫服務器上。數據庫分割可以減少每台數據庫服務器上的數據量,以便減少硬盤I/O(輸入/輸出)處理,實現內存上的高速處理,效果非常顯著。但是,由於分別存儲在不同服務器上的表之間無法進行JOIN處理,數據庫分割的時候就需要預先考慮這些問題。數據庫分割之后,如果一定要進行JOIN處理,就必須要在程序中進行關聯,這是非常困難的。下圖所示為數據庫分割。

(3) 為有數據更新的表索引表結構(schema)變更

在使用關系型數據庫時,為了加快查詢速度需要創建索引,為了增加必要的字段就一定需要改變表結構。為了進行這些處理,需要對表進行共享鎖定,這期間數據變更(更新、插入、刪除等)是無法進行的。如果需要進行一些耗時操作(例如為數據量比較大的表創建索引或者是變更其表結構),就需要特別注意:長時間內數據可能無法進行更新。下表所示為共享鎖和排他鎖。

名稱

鎖的影響范圍

別名

共享鎖

其他連接可以對數據進行讀取但是不能修改數據

讀鎖

排它鎖

其他連接無法對數據進行讀取和修改操作

寫鎖

(4) 字段不固定時的應用

如果字段不固定,利用關系型數據庫也是比較困難的。有人會說"需要的時候,加個字段就可以了",這樣的方法也不是不可以,但在實際運用中每次都進行反復的表結構變更是非常痛苦的。你也可以預先設定大量的預備字段,但這樣的話,時間一長很容易弄不清楚字段和數據的對應狀態(即哪個字段保存哪些數據),所以並不推薦使用。下圖所示為使用預備字段的情況。

(5) 對簡單查詢需要快速返回結果的處理

最后還有一點,這點似乎稱不上是缺點,但不管怎樣,關系型數據庫並不擅長對簡單這里所說的"簡單"指的是沒有復雜的查詢條件,而不是用JOIN的意思。的查詢快速返回結果。因為關系型數據庫是使用專門的SQL語言進行數據讀取的,它需要對SQL語言進行解析,同時還有對表的鎖定解鎖這樣的額外開銷。這里並不是說關系型數據庫的速度太慢,而只是想告訴大家若希望對簡單查詢進行高速處理,則沒有必要非用關系型數據庫不可

在這種情況下,我想推薦大家使用NoSQL數據庫。但是像MySQL提供了利用HandlerSocket這樣的變通方法,也是可行的。雖然使用的是關系型數據庫MySQL,但並沒有利用SQL而是直接進行數據訪問。這樣的方法是非常快速的。下圖所示為HandlerSocket的概要。

二、NoSQL數據庫

上節介紹了關系型數據庫的不足之處。為了彌補這些不足(特別是最近幾年)NoSQL數據庫出現了。關系型數據庫應用廣泛,能進行事務處理JOIN復雜處理。相對地,NoSQL數據庫只應用在特定領域,基本上不進行復雜的處理,但它恰恰彌補了之前所列舉的關系型數據庫的不足之處。

2.1   易於數據的分散

如前所述,關系型數據庫並不擅長大量數據的寫入處理。原本關系型數據庫就是以JOIN為前提的,就是說,各個數據之間存在關聯是關系型數據庫得名的主要原因。為了進JOIN處理,關系型數據庫不得不把數據存儲在同一個服務器內,這不利於數據的分散。相反,NoSQL數據庫原本就不支持JOIN處理,各個數據都是獨立設計的,很容易把數據分散到多個服務器上。由於數據被分散到了多個服務器上,減少了每個服務器上的數據量,即使要進行大量數據的寫入操作,處理起來也更加容易。同理,數據的讀入操作當然也同樣容易。

2.2   提升性能和增大規模

下面說一點題外話,如果想要使服務器能夠輕松地處理更大量的數據,那么只有兩個選擇:一是提升性能,二是增大規模。下面我們來整理一下這兩者的不同。

首先,提升性能指的就是通過提升現行服務器自身的性能來提高處理能力。這是非常簡單的方法,程序方面也不需要進行變更,但需要一些費用。若要購買性能翻倍的服務器,需要花費的資金往往不只是原來的2倍,可能需要多達5~10倍。這種方法雖然簡單,但是成本較高。下圖所示為提升性能的費用與性能曲線。

另一方面,增大規模指的是使用多台廉價的服務器來提高處理能力。它需要對程序進行變更,但由於使用廉價的服務器,可以控制成本。另外,以后只要依葫蘆畫瓢增加廉價服務器的數量就可以了。下圖所示為提升性能和增大規模。

2.3   不對大量數據進行處理的話就沒有使用的必要嗎

NoSQL數據庫基本上來說為了"使大量數據的寫入處理更加容易(讓增加服務器數量更容易)"而設計的。但如果不是對大量數據進行操作的話,NoSQL數據庫的應用就沒有意義嗎?

答案是否定的。的確,它在處理大量數據方面很有優勢。但實際上NoSQL數據庫還有各種各樣的特點,如果能夠恰當地利用這些特點,它就會非常有用。具體的,這些用途將會讓你感受到利用NoSQL的好處。

希望順暢地對數據進行緩存(Cache)處理

希望對數組類型的數據進行高速處理

■希望進行全部保存

三、多樣的NoSQL數據庫

NoSQL說起來簡單,但實際上到底有多少種呢?在官方網站上確認了一下,竟然已經有122種了。另外官方網站上也介紹了圖形數據庫對象數據庫等各個類別。目前,常見的NoSQL數據庫分為"鍵值存儲庫""文檔型數據庫""存儲數據庫"等各種各樣的種類,每種數據庫又包含各自的特點。具有代表性的Nosor數據庫如下圖所示:

臨時性鍵值存儲

永久性鍵值存儲

面向文檔的數據庫

面向列的數據庫

memcached

Tokyo Tyrant

MongoDB

Cassandra

(Redis)

Flare

CouchDB

Hbase

 

ROMA

 

HyperTable

 

(Redis)

   

3.1 鍵值存儲

這是最常見的NoSQL數據庫,它的數據是以鍵值的形式存儲的。雖然它的處理速度非常快,但是基本上只能通過鍵的完全一致查詢獲取數據。根據數據的保存方式可以分為臨時性永久性兩者兼具3種。

(1) 臨時性

所謂臨時性就是"數據有可能丟失"的意思。memcached把所有數據都保存在內存中,這樣保存和讀取的速度非常快,但是當memcached停止的時候,數據就不存在了。由於數據保存在內存中,所以無法操作超出內存容量的數據(舊數據會丟失)。

■ 在內存中保存數據

■ 可以進行非常快速的保存讀取處理

■ 數據有可能丟失

(2) 永久性

Tokyo TyrantFlareROMA等屬於這種類型。和臨時性相反,所謂永久性就是"數據不會丟失"的意思。這里的鍵值存儲不像memcached那樣在內存中保存數據,而是把數據保存在硬盤上。與memcached在內存中處理數據比起來,由於必然要發生對硬盤的IO操作,所以性能上還是有差距的。但數據不會丟失是它最大的優勢。

■ 在硬盤上保存數據

■ 可以進行非常快速的保存和讀取處理(但無法與memcached相比)

■ 數據不會丟失

(3) 兩者兼具

Redis屬於這種類型。Redis有些特殊,臨時性和永久性兼具,且集合了臨時性鍵值存儲和永久性鍵值存儲的優點鍵值。Redis首先把數據保存到內存中,在滿足特定條件(默認是1 5分鍾一次以上,5分鍾內10個以上,1分鍾內10 000個以上的鍵發生變更)的時候將數據寫入到硬盤中。這樣既確保了內存中數據的處理速度,又可以通過寫入硬盤來保證數據的永久性。這種類型的數據庫特別適合於處理數組類型的數據

■ 同時在內存硬盤上保存數據

■ 可以進行非常快速的保存讀取處理

■ 保存在硬盤上的數據不會消失可以恢復

■ 適合於處理數組類型的數據

3.2面向文檔的數據庫

MongoDBCouchDB屬於這種類型。它們屬於NoSQL數據庫,但與鍵值存儲相異

(1) 不定義表結構

面向文檔的數據庫具有以下特征:即使不定義表結構,也可以像定義了表結構一樣使用關系型數據庫在變更表結構時比較費事,而且為了保持一致性還需修改程序。然而NoSQL數據庫則可省去這些麻煩(通常程序都是正確的),確實是方便快捷。

(2) 可以使用復雜的查詢條件

跟鍵值存儲不同的是,面向文檔的數據庫可以通過復雜的查詢條件來獲取數據。雖然不具備事務處理JOIN這些關系型數據庫所具有的處理能力,但除此以外的其他處理基本上都能實現。這是非常容易使用的NoSQL數據庫。

■ 不需要定義表結構

■ 可以利用復雜的查詢條件

3.3 面向列的數據庫

CassandraHbaseHyperTable屬於這種類型。由於近年來數據量出現爆發性增長,這種類型的NoSQL數據庫尤其引人注目。

(1) 面向行的數據庫和面向列的數據庫

普通的關系型數據庫都是以行為單位來存儲數據的,擅長進行以行為單位的讀入處理,比如特定條件數據的獲取。因此,關系型數據庫也被稱為面向行的數據庫。相反,面向列的數據庫是以列為單位來存儲數據的,擅長以列為單位讀入數據。面向行的數據庫和面向列的數據庫比較如下表所示:

數據類型

數據存儲方式

優勢

面向行的數據庫

以行為單位

對少量行進行讀取和更新

面向列的數據庫

以列為單位

對大量行少數列進行讀取,對所有行的特定列同時進行更新

(2) 高擴展性

面向列的數據庫具有高擴展性即使數據增加也不會降低相應的處理速度特別是寫入速度,所以它主要應用於需要處理大量數據的情況。另外。利用面向列的數據庫的優勢,把它作為批處理程序的存儲器來對大量數據進行更新也是非常有用的。但由於面向列的數據庫跟現行數據庫存儲的思維方式有很大不同,應用起來十分困難。

■ 高擴展性{特別是寫入處理)

■ 應用十分困難

最近,像Twitter和Facebook這樣需要對大量數據進行更新和查詢的網絡服務不斷增加,面向列的數據庫的優勢對其中一些服務是非常有用的,大家有興趣可以自己研究一下。

 

如果,您認為閱讀這篇博客讓您有些收獲,不妨點擊一下右下角的【推薦】。
如果,您希望更容易地發現我的新博客,不妨點擊一下左下角的【關注我】。
如果,您對我的博客所講述的內容有興趣,請繼續關注我的后續博客,我是【Sunddenly】。

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM