隨着互聯網的不斷髮展,各類類型的應用層出不窮,因此致使在這個雲計算的時代,對技術提出了更多的需求,主要體如今下面這四個方面:
低延遲的讀寫速度:應用快速地反應能極大地提高用戶的滿意度;
支撐海量的數據和流量:對於搜索這樣大型應用而言,須要利用PB級別的數據和能應對百萬級的流量;
大規模集羣的管理:系統管理員但願分佈式應用能更簡單的部署和管理;
龐大運營成本的考量:IT經理們但願在硬件成本、軟件成本和人力成本可以有大幅度地下降;web
關係型數據庫,是指採用了關係模型來組織數據的數據庫。關係模型是在1970年由IBM的研究員E.F.Codd博士首先提出的,在以後的幾十年中,關係模型的概念獲得了充分的發展並逐漸成爲主流數據庫結構的主流模型。
簡單來講,關係模型指的就是二維表格模型,而一個關係型數據庫就是由二維表及其之間的聯繫所組成的一個數據組織。sql
雖然關係型數據庫已經在業界的數據存儲方面佔據不可動搖的地位,可是因爲其天生的幾個限制,使其很難知足上面這幾個需求 數據庫
高併發讀寫需求:網站的用戶併發性很是高,每每達到每秒上萬次讀寫請求,對於傳統關係型數據庫來講,硬盤I/O是一個很大的瓶頸(隨機I/O);
海量數據的高效率讀寫:網站天天產生的數據量是巨大的,對於關係型數據庫來講,在一張包含海量數據的表中查詢,效率是很是低的;
高擴展性和可用性:在基於web的結構當中,數據庫是最難進行橫向擴展的,當一個應用系統的用戶量和訪問量與日俱增的時候,數據庫卻沒有辦法像web server和app server那樣簡單的經過添加更多的硬件和服務節點來擴展性能和負載能力。對於不少須要提供24小時不間斷服務的網站來講,對數據庫系統進行升級和擴展 是很是痛苦的事情,每每須要停機維護和數據遷移。
對網站來講,關係型數據庫的不少特性再也不須要了:
事務一致性:關係型數據庫在對事物一致性的維護中有很大的開銷,而如今不少web2.0系統對事物的讀寫一致性都不高
讀寫實時性:對關係數據庫來講,插入一條數據以後馬上查詢,是確定能夠讀出這條數據的,可是對於不少web應用來講,並不要求這麼高的實時性,好比發一條消息以後,過幾秒乃至十幾秒以後纔看到這條動態是徹底能夠接受的
複雜SQL,特別是多表關聯查詢:任何大數據量的web系統,都很是忌諱多個大表的關聯查詢,以及複雜的數據分析類型的複雜SQL報表查詢,特別是SNS類型的網站,從需求以及產品階級角度,就避免了這種狀況的產生。每每更多的只是單表的主鍵查詢,以及單表的簡單條件分頁查詢,SQL的功能極大的弱化了
SNS (Social Networking Services 社交網絡服務)專指社交網絡服務,包括了社交軟件和社交網站。
CIO (Chief Information Officer 首席信息官)
在關係型數據庫中,致使性能欠佳的最主要緣由是多表的關聯查詢,以及複雜的數據分析類型的複雜SQL報表查詢。爲了保證數據庫的ACID特性,咱們 必須儘可能按照其要求的範式進行設計,關係型數據庫中的表都是存儲一個格式化的數據結構。每一個元組字段的組成都是同樣,即便不是每一個元組都須要全部的字段, 但數據庫會爲每一個元組分配全部的字段,這樣的結構能夠便於表與表之間進行連接等操做,但從另外一個角度來講它也是關係型數據庫性能瓶頸的一個因素。json
NoSQL一詞首先是Carlo Strozzi在1998年提出來的,指的是他開發的一個沒有SQL功能,輕量級的,開源的關係型數據庫。這個定義跟咱們如今對NoSQL的定義有很大的 區別,它確確實實字如其名,指的就是「沒有SQL」的數據庫。可是NoSQL的發展慢慢偏離了初衷,咱們要的不是「no sql」,而是「no relational」,也就是咱們如今常說的非關係型數據庫了。
2009年初,Johan Oskarsson舉辦了一場關於開源分佈式數據庫的討論,Eric Evans在此次討論中再次提出了NoSQL一詞,用於指代那些非關係型的,分佈式的,且通常不保證遵循ACID原則的數據存儲系統。Eric Evans使用NoSQL這個詞,並非由於字面上的「沒有SQL」的意思,他只是以爲不少經典的關係型數據庫名字都叫「**SQL」,因此爲了表示跟這些關係型數據庫在定位上的大相徑庭,就是用了「NoSQL「一詞。
注:數據庫事務必須具有ACID特性,ACID是Atomic原子性,Consistency一致性,Isolation隔離性,Durability持久性。
非關係型數據庫提出另外一種理念,例如,以鍵值對存儲,且結構不固定,每個元組能夠有不同的字段,每一個元組能夠根據須要增長一些本身的鍵值對,這 樣就不會侷限於固定的結構,能夠減小一些時間和空間的開銷。使用這種方式,用戶能夠根據須要去添加本身須要的字段,這樣,爲了獲取用戶的不一樣信息,不須要 像關係型數據庫中,要對多表進行關聯查詢。僅須要根據id取出相應的value就能夠完成查詢。但非關係型數據庫因爲不多的約束,他也不可以提供像SQL 所提供的where這種對於字段屬性值狀況的查詢。而且難以體現設計的完整性。他只適合存儲一些較爲簡單的數據,對於須要進行較複雜查詢的數據,SQL數 據庫顯的更爲合適。服務器
NoSQL具備靈活的數據模型,能夠處理非結構化/半結構化的大數據
面對豐富多樣的數據,構建的應用須要使用很是靈活的數據存儲系統,可以輕鬆容納新的數據類型,而且不會被第三方數據提供商內容結構的變化所累。NoSQL提供的數據模型則能很好地知足這種需求。經過這種靈活性存儲數據而無需修改表或是建立更多的列。很是適合於建立原型或是快速應用,這種靈活性使得新特性的開發變得很是容易。
NoSQL很容易實現可伸縮性(向上擴展與水平擴展)
RDBMS是中心化的,向上擴展而非水平擴展的。這使得他們不適合於那些須要簡單且動態可伸縮性的應用。NoSQL數據庫從一開始就是分佈式、水平擴展的,所以很是適合於互聯網應用分佈式的特性。網絡
關係型數據庫須要在添加數據前先定義好模式。這對於敏捷開發模式來講是場災難,由於每次完成新特性時,數據庫的模式一般都須要改變。數據結構
NoSQL數據庫一般都支持自動分片,這意味着他們本質上就會自動在多臺服務器上分發數據,應用甚至都不知道這些事情。數據與查詢負載會自動在多臺服務器上作到平衡,當某臺服務器當機時,它能快速且透明地被替換掉。架構
大多數NoSQL數據庫也支持自動複製,這意味着你能夠得到高可用性與災備恢復功能。從開發者的角度來看,存儲環境本質上是虛擬化的。併發
NoSQL數據庫種類繁多,可是一個共同的特色都是去掉關係數據庫的關係型特性。數據之間無關係,這樣就很是容易擴展。也無形之間,在架構的層面上帶來了可擴展的能力。app
NoSQL數據庫都具備很是高的讀寫性能,尤爲在大數據量下,一樣表現優秀。這得益於它的無關係性,數據庫的結構簡單。通常MySQL使用Query Cache,每次表的更新Cache就失效,是一種大粒度的Cache,在針對web2.0的交互頻繁的應用,Cache性能不高。而NoSQL的Cache是記錄級的,是一種細粒度的Cache,因此NoSQL在這個層面上來講就要性能高不少了。
NoSQL無需事先爲要存儲的數據創建字段,隨時能夠存儲自定義的數據格式。而在關係數據庫裏,增刪字段是一件很是麻煩的事情。若是是很是大數據量的表,增長字段簡直就是一個噩夢。這點在大數據量的web2.0時代尤爲明顯。
NoSQL在不太影響性能的狀況,就能夠方便的實現高可用的架構。好比Cassandra,HBase模型,經過複製模型也能實現高可用。
簡單的擴展:典型例子是Cassandra,因爲其架構是相似於經典的P2P,因此能經過輕鬆地添加新的節點來擴展這個集羣;
快速的讀寫:主要例子有Redis,因爲其邏輯簡單,並且純內存操做,使得其性能很是出色,單節點每秒能夠處理超過10萬次讀寫操做;
低廉的成本:這是大多數分佈式數據庫共有的特色,由於主要都是開源軟件,沒有昂貴的License成本;
但瑕不掩瑜,NoSQL數據庫還存在着不少的不足,常見主要有下面這幾個:
不提供對SQL的支持:若是不支持SQL這樣的工業標準,將會對用戶產生必定的學習和應用遷移成本;
支持的特性不夠豐富:現有產品所提供的功能都比較有限,大多數NoSQL數據庫都不支持事務,也不像MS SQL Server和Oracle那樣能提供各類附加功能,好比BI和報表等;
現有產品的不夠成熟:大多數產品都還處於初創期,和關係型數據庫幾十年的完善不可同日而語;
RDBMS系統由來已久。NoSQL擁護者們會說RDBMS的高齡是其衰退的標誌,不過對於大多數CIO來講,RDBMS的成熟讓人放心。對於大多數狀況來講,RDBMS系統是穩定且功能豐富的。相比較而言,大多數NoSQL數據庫則還有不少特性有待實現。
企業須要的是安心,若是關鍵系統出現了故障,他們能夠得到即時的支持。全部RDBMS廠商都在竭盡全力地提供良好的企業支持。與之相反,大多數NoSQL系統都是開源項目,雖然每種數據庫都有那麼幾家公司提供支持,不過這些公司大多都是小的初創公司,沒有全球支持資源,也沒有Oracle、微軟或是IBM那種使人放心的公信力。
NoSQL數據庫在Web 2.0應用時代開始出現。所以,大多數特性都是面向這些應用的須要的。然而,應用中的數據對於業務來講是有價值的,這種價值遠遠超出了Web應用那種CRUD。企業數據庫中的業務信息能夠幫助改進效率並提高競爭力,商業智能對於大中型企業來講是個很是關鍵的IT問題。
NoSQL的設計目標是提供零管理的解決方案,不過當今的現實卻離這個目標還相去甚遠。如今的NoSQL須要不少技巧才能用好,而且須要很多人力、物力來維護。
數據庫表schema常常變化
好比在線商城,維護產品的屬性常常要增長字段,這就意味着ORMapping層的代碼和配置要改,若是該表的數據量過百萬,新增字段會帶來額外開銷(重建索引等)。NoSQL應用在這種場景,能夠極大提高DB的可伸縮性,開發人員能夠將更多的精力放在業務層。
數據庫表字段是複雜數據類型
對於複雜數據類型,好比SQL Sever提供了可擴展性的支持,像xml類型的字段。不少用過的同窗應該知道,該字段無論是查詢仍是更改,效率很是通常。主要緣由是是DB層對xml字段很難建高效索引,應用層又要作從字符流到dom的解析轉換。NoSQL以json方式存儲,提供了原生態的支持,在效率方便遠遠高於傳統關係型數據庫。
高併發數據庫請求
此類應用常見於web2.0的網站,不少應用對於數據一致性要求很低,而關係型數據庫的事務以及大表join反而成了」性能殺手」。在高併發狀況下,sql與no-sql的性能對比因爲環境和角度不一樣一直是存在爭議的,並非說在任何場景,no-sql老是會比sql快。有篇article和你們分享下,http://artur.ejsmont.org/blog/content/insert-performance-comparison-of-nosql-vs-sql-servers
海量數據的分佈式存儲
海量數據的存儲若是選用大型商用數據,如Oracle,那麼整個解決方案的成本是很是高的,要花不少錢在軟硬件上。NoSQL分佈式存儲,能夠部署在廉價的硬件上,是一個性價比很是高的解決方案。
因爲非關係型數據庫自己自然的多樣性,以及出現的時間較短,所以,不想關係型數據庫,有幾種數據庫可以一統江山,非關係型數據庫很是多,而且大部分都是開源的。
這些數據庫中,其實實現大部分都比較簡單,除了一些共性外,很大一部分都是針對某些特定的應用需求出現的,所以,對於該類應用,具備極高的性能。依據結構化方法以及應用場合的不一樣,主要分爲如下幾類:
面向高性能併發讀寫的key-value數據庫:
key-value數據庫的主要特色即便具備極高的併發讀寫性能,Redis,Tokyo Cabinet,Flare就是這類的表明
面向海量數據訪問的面向文檔數據庫:
這類數據庫的特色是,能夠在海量的數據中快速的查詢數據,典型表明爲MongoDB以及CouchDB
面向可擴展性的分佈式數據庫:
這類數據庫想解決的問題就是傳統數據庫存在可擴展性上的缺陷,這類數據庫能夠適應數據量的增長以及數據結構的變化
關係型數據庫的最大特色就是事務的一致性:傳統的關係型數據庫讀寫操做都是事務的,具備ACID的特色,這個特性使得關係型數據庫能夠用於幾乎全部對一致性有要求的系統中,如典型的銀行系統。
可是,在網頁應用中,尤爲是SNS應用中,一致性卻不是顯得那麼重要,用戶A看到的內容和用戶B看到同一用戶C內容更新不一致是能夠容忍的,或者 說,兩我的看到同一好友的數據更新的時間差那麼幾秒是能夠容忍的,所以,關係型數據庫的最大特色在這裏已經無用武之地,起碼不是那麼重要了。
相反地,關係型數據庫爲了維護一致性所付出的巨大代價就是其讀寫性能比較差,而像微博、facebook這類SNS的應用,對併發讀寫能力要求極 高,關係型數據庫已經沒法應付(在讀方面,傳統上爲了克服關係型數據庫缺陷,提升性能,都是增長一級memcache來靜態化網頁,而在SNS中,變化太 快,memchache已經無能爲力了),所以,必須用新的一種數據結構存儲來代替關係數據庫。
關係數據庫的另外一個特色就是其具備固定的表結構,所以,其擴展性極差,而在SNS中,系統的升級,功能的增長,每每意味着數據結構巨大變更,這一點關係型數據庫也難以應付,須要新的結構化數據存儲。
因而,非關係型數據庫應運而生,因爲不可能用一種數據結構化存儲應付全部的新的需求,所以,非關係型數據庫嚴格上不是一種數據庫,應該是一種數據結構化存儲方法的集合。
必須強調的是,數據的持久存儲,尤爲是海量數據的持久存儲,仍是須要一種關係數據庫這員老將。