天天看點

NoSql入門

什麼是No-Sql

概念:

NoSQL(NoSql = Not Only Sql), 意思是 “不僅僅是SQL” 範指非關系型的資料庫。不是傳統的關系型資料庫

解析:

泛指非關系型的資料庫。随着網際網路web2.0網站的興起,傳統的關系資料庫在應付web2.0網站,特别是超大規模和高并發的SNS類型的web2.0純動态網站已經顯得力不從心。

為什麼要使用NoSql資料庫

網際網路的瓶頸

1. 高并發讀寫

–針對短時間内具有高并發的情況,特别是短時間内大量的寫入操作。傳統資料庫針對這種情況就有些力不從心了。

2. 海量資料的高效率存儲和通路

–現在的資料已經是非常龐大了,一些大型網站每天産生的資料量是相當恐怖的。存儲了這麼多的資料,查詢效率就會受到很大的影響。

3. 高科擴充性和高可用性

– 基于傳統資料庫的結構,我們的資料庫表是非常難以橫向擴充的,比如增加一個新的字段 時或者修改某個字段時,牽一發而動全身。

4. 資料存儲的方式單一。

– 在資料庫中針對形形色色的資料,我們都隻有采用表結構的方式來存儲資料。

web2.0特别是一些使用者通路量比較大的網站如:www.taobao.com weibo.com baidu.com

每秒的通路量可能是上萬次(10K);傳統的關系型資料庫 mysql oracle 每秒進行10K次資料查詢還可以勉強應付,但是如果是每秒10K次讀寫資料庫,因為資料庫的資料都是解除安裝磁盤中,是以磁盤IO也是支撐不住每秒10K的讀寫。

在web的架構中,資料庫是最難進行橫向擴充的(通過簡單的添加機器和硬體,也就是添加一些服務節點來提高負載均衡能力);對于7*24小時線上的網站來說,對關系型資料庫進行更新和擴充(分布式擴充–分庫分表)是非常痛苦的事情,往往要進行停機維護;但這種對www.taobao.com 來說是非常醜陋的事情。[–可不可以添加幾台伺服器然後把複制,然後進行負載均衡–]。

NoSQL 是采用key/value的結構來存儲資料,而且大多數的NoSQL采用記憶體來存儲資料,一段時間後把資料同步到磁盤中;由于使用記憶體儲存資料很好地解決了高并發讀寫的問題;其次NoSQL提供了根據key值進行橫向分表(比如:使用者id,每2000w資料放到一台資料庫伺服器中的一張使用者表中);同時實作了主從資料庫互備,這樣可以讓資料庫的動态遷移變得簡單,讓資料庫伺服器的橫向擴充變得容易了。

關系型資料庫的優勢:

1. 保持資料的一緻性(事務處理)—— 保持資料的一緻性是關系型資料庫最大的優勢

2. 由于以标準化為前提,資料更新的開銷很小(相同字段基本上隻有一處)

3. 可以進行Join 等複雜查詢

關系型資料的不足:

大量資料的寫入處理

----讀寫集中在一個資料庫上讓資料庫不堪重負,大部分網站已使用主從複制技術實作讀寫分離,以提高讀寫性能和讀庫的可擴充性。是以在進行大量資料操作時,會使用資料庫的主從模式,資料的寫入由主資料庫負責,資料的讀入由從資料庫負責,可以比較簡單地通過增加從資料庫來實作規模化,但是資料的寫入卻完全沒有簡單的方法來解決規模化問題。

解決方法:

①:要想将資料的寫入規模化,可以考慮把主資料庫從一台增加到兩台,作為互相關聯複制的二進制主資料庫使用,确實這樣可以把每台主資料庫的負荷減少一半,但是更新處理會發生沖突,可能會造成資料的不一緻,為了避免這樣的問題,需要把對每個表的請求分别配置設定給合适的主資料庫來處理。

②:可以考慮把資料庫分割開來,分别放在不同的資料庫伺服器上,比如将不同的表放在不同的資料庫伺服器上,資料庫分割可以減少每台資料庫伺服器上的資料量,以便減少硬碟IO的輸入、輸出處理,實作記憶體上的高速處理。但是由于分别存儲字不同伺服器上的表之間無法進行Join處理,資料庫分割的時候就需要預先考慮這些問題,資料庫分割之後,如果一定要進行Join處理,就必須要在程式中進行關聯,這是非常困難的。

為有資料更新表的索引或表結構變更

----在使用關系型資料庫時,為了加快查詢速度需要建立索引,為了增加必要的字段就一定要改變表結構,為了進行這些處理,需要對表進行共享鎖定,這期間資料變更、更新、插入、删除等都是無法進行的。如果需要進行一些耗時操作,例如為資料量比較大的表建立索引或是變更其表結構,就需要特别注意,長時間内資料可能無法進行更新。

字段不固定時應用

----如果字段不固定,利用關系型資料庫也是比較困難的,有人會說,需要的時候加個字段就可以了,這樣的方法也不是不可以,但在實際運用中每次都進行反複的表結構變更是非常痛苦的。你也可以預先設定大量的預備字段,但這樣的話,時間一長很容易弄不清除字段和資料的對應狀态,即哪個字段儲存有哪些資料。

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

----這一點稱不上是缺點,但不管怎樣,關系型資料庫并不擅長對簡單的查詢快速傳回結果,因為關系型資料庫是使用專門的sql語言進行資料讀取的,它需要對sql與越南進行解析,同時還有對表的鎖定和解鎖等這樣的額外開銷,這裡并不是說關系型資料庫的速度太慢,而隻是想告訴大家若希望對簡單查詢進行高速處理,則沒有必要非使用關系型資料庫不可

NoSql資料庫的優勢

易擴充

–NoSQL資料庫種類繁多,但是一個共同的特點都是去掉關系資料庫的關系型特性。資料之間無關系,這樣就非常容易擴充。也無形之間,在架構的層面上帶來了可擴充的能力。

大資料量性能高

–NoSQL資料庫都具有非常高的讀寫性能,尤其在大資料量下,同樣表現優秀。這得益于它的無關系性,資料庫的結構簡單。一般MySQL使用Query Cache,每次表的更新Cache就失效,是一種大粒度的Cache,在針對web2.0的互動頻繁的應用,Cache性能不高。而NoSQL的Cache是記錄級的,是一種細粒度的Cache,是以NoSQL在這個層面上來說就要性能高很多了

多樣靈活的資料模型

–NoSQL無需事先為要存儲的資料建立字段,随時可以存儲自定義的資料格式。而在關系資料庫裡,增删字段是一件非常麻煩的事情。如果是非常大資料量的表,增加字段簡直就是一個噩夢

典型的NoSQL資料庫

臨時性鍵值存儲(memcached、Redis)、永久性鍵值存儲(ROMA、Redis)、面向文檔的資料庫(MongoDB、CouchDB)、面向列的資料庫(Cassandra、HBase)

一、 鍵值存儲

它的資料是以鍵值的形式存儲的,雖然它的速度非常快,但基本上隻能通過鍵的完全一緻查詢擷取資料,根據資料的儲存方式可以分為臨時性、永久性和兩者兼具 三種。

(1)臨時性

所謂臨時性就是資料有可能丢失,memcached把所有資料都儲存在記憶體中,這樣儲存和讀取的速度非常快,但是當memcached停止時,資料就不存在了。由于資料儲存在記憶體中,是以無法操作超出記憶體容量的資料,舊資料會丢失。總結來說:

。在記憶體中儲存資料

。可以進行非常快速的儲存和讀取處理

。資料有可能丢失

(2)永久性

所謂永久性就是資料不會丢失,這裡的鍵值存儲是把資料儲存在硬碟上,與臨時性比起來,由于必然要發生對硬碟的IO操作,是以性能上還是有差距的,但資料不會丢失是它最大的優勢。總結來說:

。在硬碟上儲存資料

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

。資料不會丢失

(3) 兩者兼備

Redis屬于這種類型。Redis有些特殊,臨時性和永久性兼具。Redis首先把資料儲存在記憶體中,在滿足特定條件(預設是 15分鐘一次以上,5分鐘内10個以上,1分鐘内10000個以上的鍵發生變更)的時候将資料寫入到硬碟中,這樣既確定了記憶體中資料的處理速度,又可以通過寫入硬碟來保證資料的永久性,這種類型的資料庫特别适合處理數組類型的資料。總結來說:

。同時在記憶體和硬碟上儲存資料

。可以進行非常快速的儲存和讀取處理

。儲存在硬碟上的資料不會消失(可以恢複)

。适合于處理數組類型的資料

二、面向文檔的資料庫

MongoDB、CouchDB屬于這種類型,它們屬于NoSQL資料庫,但與鍵值存儲相異。

(1)不定義表結構

   即使不定義表結構,也可以像定義了表結構一樣使用,還省去了變更表結構的麻煩。

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

   跟鍵值存儲不同的是,面向文檔的資料庫可以通過複雜的查詢條件來擷取資料,雖然不具備事務處理和Join這些關系型資料庫所具有的處理能力,但初次以外的其他處理基本上都能實作。

  

三、 面向列的資料庫

Cassandra、HBae、HyperTable屬于這種類型,由于近年來資料量出現爆發性增長,這種類型的NoSQL資料庫尤其引入注目。

普通的關系型資料庫都是以行為機關來存儲資料的,擅長以行為機關的讀入處理,比如特定條件資料的擷取。是以,關系型資料庫也被成為面向行的資料庫。相反,面向列的資料庫是以列為機關來存儲資料的,擅長以列為機關讀入資料。

四、圖形資料庫(這裡就不作介紹了)

三種對比

  1. key-value:内容緩存,主要用于處理大量資料的高通路負載,也用于一些日志系統等。優點:查詢速度快。缺點:資料無結構化,通常隻被當做字元串或者二進制資料。
  2. 列存儲:分布式檔案系統。優點:查找速度快,可擴充性強,更容易進行分布式擴充。缺點:功能相對局限。
  3. 文檔型:與key-value類似,不同的是資料庫能夠了解value的内容。優點:資料結構要求不嚴格,表結構可變,不需要預先定義表結構。缺點:查詢效率不高,缺乏統一的文法。
  4. 圖形:社交網絡,推薦系統。專注于建構關系圖譜。優點:利用圖形結構相關算法,來尋求最短路徑。缺點:很多時候需要對整個圖形計算才能得出需要的資訊。