NoSQL還是SQL?這一篇講清楚
原創(chuàng)【51CTO.com原創(chuàng)稿件】傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)在應(yīng)付這些已經(jīng)顯得力不從心,并暴露了許多難以克服的問題。
由此,各種各樣的 NoSQL(Not Only SQL)數(shù)據(jù)庫(kù)作為傳統(tǒng)關(guān)系型數(shù)據(jù)的一個(gè)有力補(bǔ)充得到迅猛發(fā)展。
本文將分析傳統(tǒng)數(shù)據(jù)庫(kù)存在的一些問題,以及幾大類 NoSQL 如何解決這些問題,希望給大家提供一些在不同業(yè)務(wù)場(chǎng)景下存儲(chǔ)技術(shù)選型方面的參考。
傳統(tǒng)數(shù)據(jù)庫(kù)的缺點(diǎn)
傳統(tǒng)的數(shù)據(jù)庫(kù)有如下幾個(gè)缺點(diǎn):
- 大數(shù)據(jù)場(chǎng)景下 I/O 較高,因?yàn)閿?shù)據(jù)是按行存儲(chǔ),即使只針對(duì)其中某一列進(jìn)行運(yùn)算,關(guān)系型數(shù)據(jù)庫(kù)也會(huì)將整行數(shù)據(jù)從存儲(chǔ)設(shè)備中讀入內(nèi)存,導(dǎo)致 I/O 較高。
- 存儲(chǔ)的是行記錄,無法存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)。
- 表結(jié)構(gòu) Schema 擴(kuò)展不方便,如要修改表結(jié)構(gòu),需要執(zhí)行 DDL(data definition language),語句修改,修改期間會(huì)導(dǎo)致鎖表,部分服務(wù)不可用。
- 全文搜索功能較弱,關(guān)系型數(shù)據(jù)庫(kù)下只能夠進(jìn)行子字符串的匹配查詢,當(dāng)表的數(shù)據(jù)逐漸變大的時(shí)候,like 查詢的匹配會(huì)非常慢,即使在有索引的情況下。況且關(guān)系型數(shù)據(jù)庫(kù)也不應(yīng)該對(duì)文本字段進(jìn)行索引。
- 存儲(chǔ)和處理復(fù)雜關(guān)系型數(shù)據(jù)功能較弱,許多應(yīng)用程序需要了解和導(dǎo)航高度連接數(shù)據(jù)之間的關(guān)系,才能啟用社交應(yīng)用程序、推薦引擎、欺詐檢測(cè)、知識(shí)圖譜、生命科學(xué)和 IT/網(wǎng)絡(luò)等用例。
然而傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)并不善于處理數(shù)據(jù)點(diǎn)之間的關(guān)系。它們的表格數(shù)據(jù)模型和嚴(yán)格的模式使它們很難添加新的或不同種類的關(guān)聯(lián)信息。
NoSQL 解決方案
NoSQL,泛指非關(guān)系型的數(shù)據(jù)庫(kù),可以理解為 SQL 的一個(gè)有力補(bǔ)充。
在 NoSQL 許多方面性能大大優(yōu)于非關(guān)系型數(shù)據(jù)庫(kù)的同時(shí),往往也伴隨一些特性的缺失,比較常見的是事務(wù)庫(kù)事務(wù)功能的缺失。
數(shù)據(jù)庫(kù)事務(wù)正確執(zhí)行的四個(gè)基本要素 ACID 如下:
下面介紹 5 大類 NoSQL 數(shù)據(jù)針對(duì)傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)的缺點(diǎn)和提供的解決方案:
列式數(shù)據(jù)庫(kù)
列式數(shù)據(jù)庫(kù)是以列相關(guān)存儲(chǔ)架構(gòu)進(jìn)行數(shù)據(jù)存儲(chǔ)的數(shù)據(jù)庫(kù),主要適合于批量數(shù)據(jù)處理和即時(shí)查詢。
相對(duì)應(yīng)的是行式數(shù)據(jù)庫(kù),數(shù)據(jù)以行相關(guān)的存儲(chǔ)體系架構(gòu)進(jìn)行空間分配,主要適合于小批量的數(shù)據(jù)處理,常用于聯(lián)機(jī)事務(wù)型數(shù)據(jù)處理。
基于列式數(shù)據(jù)庫(kù)的列列存儲(chǔ)特性,可以解決某些特定場(chǎng)景下關(guān)系型數(shù)據(jù)庫(kù) I/O 較高的問題。
基本原理
傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)是按照行來存儲(chǔ)數(shù)據(jù)庫(kù),稱為“行式數(shù)據(jù)庫(kù)”,而列式數(shù)據(jù)庫(kù)是按照列來存儲(chǔ)數(shù)據(jù)。
將表放入存儲(chǔ)系統(tǒng)中有兩種方法,而我們絕大部分是采用行存儲(chǔ)的。行存儲(chǔ)法是將各行放入連續(xù)的物理位置,這很像傳統(tǒng)的記錄和文件系統(tǒng)。
列存儲(chǔ)法是將數(shù)據(jù)按照列存儲(chǔ)到數(shù)據(jù)庫(kù)中,與行存儲(chǔ)類似。下圖是兩種存儲(chǔ)方法的圖形化解釋:
常見列式數(shù)據(jù)庫(kù)
HBase:是一個(gè)開源的非關(guān)系型分布式數(shù)據(jù)庫(kù)(NoSQL),它參考了谷歌的 BigTable 建模,實(shí)現(xiàn)的編程語言為 Java。
它是 Apache 軟件基金會(huì)的 Hadoop 項(xiàng)目的一部分,運(yùn)行于 HDFS 文件系統(tǒng)之上,為 Hadoop 提供類似于 BigTable 規(guī)模的服務(wù)。因此,它可以容錯(cuò)地存儲(chǔ)海量稀疏的數(shù)據(jù)。
BigTable:是一種壓縮的、高性能的、高可擴(kuò)展性的,基于 Google 文件系統(tǒng)(Google File System,GFS)的數(shù)據(jù)存儲(chǔ)系統(tǒng),用于存儲(chǔ)大規(guī)模結(jié)構(gòu)化數(shù)據(jù),適用于云端計(jì)算。
相關(guān)特性
優(yōu)點(diǎn)如下:
高效的儲(chǔ)存空間利用率:列式數(shù)據(jù)庫(kù)由于其針對(duì)不同列的數(shù)據(jù)特征而發(fā)明的不同算法使其往往有比行式數(shù)據(jù)庫(kù)高的多的壓縮率。
普通的行式數(shù)據(jù)庫(kù)一般壓縮率在 3:1 到 5:1 左右,而列式數(shù)據(jù)庫(kù)的壓縮率一般在 8:1 到 30:1 左右。
比較常見的,通過字典表壓縮數(shù)據(jù): 下面中才是那張表本來的樣子。經(jīng)過字典表進(jìn)行數(shù)據(jù)壓縮后,表中的字符串才都變成數(shù)字了。
正因?yàn)槊總€(gè)字符串在字典表里只出現(xiàn)一次了,所以達(dá)到了壓縮的目的(有點(diǎn)像規(guī)范化和非規(guī)范化 Normalize 和 Denomalize)。
查詢效率高:讀取多條數(shù)據(jù)的同一列效率高,因?yàn)檫@些列都是存儲(chǔ)在一起的,一次磁盤操作可以把數(shù)據(jù)的指定列全部讀取到內(nèi)存中。
下圖通過一條查詢的執(zhí)行過程說明列式存儲(chǔ)(以及數(shù)據(jù)壓縮)的優(yōu)點(diǎn)。
執(zhí)行步驟如下:
- 去字典表里找到字符串對(duì)應(yīng)數(shù)字(只進(jìn)行一次字符串比較)。
- 用數(shù)字去列表里匹配,匹配上的位置設(shè)為 1。
- 把不同列的匹配結(jié)果進(jìn)行位運(yùn)算得到符合所有條件的記錄下標(biāo)。
- 使用這個(gè)下標(biāo)組裝出最終的結(jié)果集。
列式數(shù)據(jù)庫(kù)還適合做聚合操作,適合大量的數(shù)據(jù)而不是小數(shù)據(jù)。
缺點(diǎn)如下:
- 不適合掃描小量數(shù)據(jù)。
- 不適合隨機(jī)的更新。
- 不適合做含有刪除和更新的實(shí)時(shí)操作。
- 單行的數(shù)據(jù)是 ACID 的,多行的事務(wù)時(shí),不支持事務(wù)的正常回滾,支持 I(Isolation)隔離性(事務(wù)串行提交),D(Durability)持久性,不能保證 A(Atomicity)原子性, C(Consistency)一致性。
使用場(chǎng)景
以 HBase 為例說明:
- 大數(shù)據(jù)量(100s TB級(jí)數(shù)據(jù)),且有快速隨機(jī)訪問的需求。
- 寫密集型應(yīng)用,每天寫入量巨大,而相對(duì)讀數(shù)量較小的應(yīng)用,比如 IM 的歷史消息,游戲的日志等等。
- 不需要復(fù)雜查詢條件來查詢數(shù)據(jù)的應(yīng)用,HBase 只支持基于 rowkey 的查詢,對(duì)于 HBase 來說,單條記錄或者小范圍的查詢是可以接受的。
大范圍的查詢由于分布式的原因,可能在性能上有點(diǎn)影響,HBase 不適用于有 join,多級(jí)索引,表關(guān)系復(fù)雜的數(shù)據(jù)模型。
- 對(duì)性能和可靠性要求非常高的應(yīng)用,由于 HBase 本身沒有單點(diǎn)故障,可用性非常高。
- 數(shù)據(jù)量較大,而且增長(zhǎng)量無法預(yù)估的應(yīng)用,需要進(jìn)行優(yōu)雅的數(shù)據(jù)擴(kuò)展的 HBase 支持在線擴(kuò)展,即使在一段時(shí)間內(nèi)數(shù)據(jù)量呈井噴式增長(zhǎng),也可以通過 HBase 橫向擴(kuò)展來滿足功能。
- 存儲(chǔ)結(jié)構(gòu)化和半結(jié)構(gòu)化的數(shù)據(jù)。
K-V 數(shù)據(jù)庫(kù)
指的是使用鍵值(key-value)存儲(chǔ)的數(shù)據(jù)庫(kù),其數(shù)據(jù)按照鍵值對(duì)的形式進(jìn)行組織、索引和存儲(chǔ)。
K-V 存儲(chǔ)非常適合不涉及過多數(shù)據(jù)關(guān)系業(yè)務(wù)關(guān)系的數(shù)據(jù),同時(shí)能有效減少讀寫磁盤的次數(shù),比 SQL 數(shù)據(jù)庫(kù)存儲(chǔ)擁有更好的讀寫性能,能夠解決關(guān)系型數(shù)據(jù)庫(kù)無法存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)的問題。
常見 K-V 數(shù)據(jù)庫(kù)
Redis:是一個(gè)使用 ANSI C 編寫的開源、支持網(wǎng)絡(luò)、基于內(nèi)存、可選持久性的鍵值對(duì)存儲(chǔ)數(shù)據(jù)庫(kù)。
從 2015 年 6 月開始,Redis 的開發(fā)由 Redis Labs 贊助,而 2013 年 5 月至 2015 年 6 月期間,其開發(fā)由 Pivotal 贊助。
在 2013 年 5 月之前,其開發(fā)由 VMware 贊助。根據(jù)月度排行網(wǎng)站 DB-Engines.com 的數(shù)據(jù)顯示,Redis 是***的鍵值對(duì)存儲(chǔ)數(shù)據(jù)庫(kù)。
Cassandra:Apache Cassandra(社區(qū)內(nèi)一般簡(jiǎn)稱為C*)是一套開源分布式 NoSQL 數(shù)據(jù)庫(kù)系統(tǒng)。
它最初由 Facebook 開發(fā),用于儲(chǔ)存收件箱等簡(jiǎn)單格式數(shù)據(jù),集 Google BigTable 的數(shù)據(jù)模型與 Amazon Dynamo 的完全分布式架構(gòu)于一身。
Facebook 于 2008 將 Cassandra 開源,此后,由于 Cassandra 良好的可擴(kuò)展性和性能。
它被 Apple,Comcas,Instagram,Spotify,eBay,Rackspace,Netflix 等知名網(wǎng)站所采用,成為了一種流行的分布式結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)方案。
LevelDB:是一個(gè)由 Google 公司所研發(fā)的鍵/值對(duì)(Key/Value Pair)嵌入式數(shù)據(jù)庫(kù)管理系統(tǒng)編程庫(kù), 以開源的 BSD 許可證發(fā)布。
相關(guān)特性
以 Redis 為例,K-V 數(shù)據(jù)庫(kù)優(yōu)點(diǎn)如下:
- 性能極高:Redis 能支持超過 10W 的 TPS。
- 豐富的數(shù)據(jù)類型:Redis 支持包括 String,Hash,List,Set,Sorted Set,Bitmap 和 Hyperloglog。
- 豐富的特性:Redis 還支持 publish/subscribe,通知,key 過期等等特性。
缺點(diǎn)如下:
- 針對(duì) ACID,Redis 事務(wù)不能支持原子性和持久性(A 和 D),只支持隔離性和一致性(I 和 C) 。
特別說明一下,這里所說的無法保證原子性,是針對(duì) Redis 的事務(wù)操作,因?yàn)槭聞?wù)是不支持回滾(roll back),而因?yàn)?Redis 的單線程模型,Redis 的普通操作是原子性的。
大部分業(yè)務(wù)不需要嚴(yán)格遵循 ACID 原則,例如游戲?qū)崟r(shí)排行榜,粉絲關(guān)注等場(chǎng)景,即使部分?jǐn)?shù)據(jù)持久化失敗,其實(shí)業(yè)務(wù)影響也非常小。因此在設(shè)計(jì)方案時(shí),需要根據(jù)業(yè)務(wù)特征和要求來做選擇。
使用場(chǎng)景
適用場(chǎng)景:
- 儲(chǔ)存用戶信息(比如會(huì)話)、配置文件、參數(shù)、購(gòu)物車等等。這些信息一般都和 ID(鍵)掛鉤。
不適用場(chǎng)景:
- 需要通過值來查詢,而不是鍵來查詢。Key-Value 數(shù)據(jù)庫(kù)中根本沒有通過值查詢的途徑。
- 需要儲(chǔ)存數(shù)據(jù)之間的關(guān)系。在 Key-Value 數(shù)據(jù)庫(kù)中不能通過兩個(gè)或以上的鍵來關(guān)聯(lián)數(shù)據(jù)。
- 需要事務(wù)的支持。在 Key-Value 數(shù)據(jù)庫(kù)中故障產(chǎn)生時(shí)不可以進(jìn)行回滾。
文檔數(shù)據(jù)庫(kù)
文檔數(shù)據(jù)庫(kù)(也稱為文檔型數(shù)據(jù)庫(kù))是旨在將半結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)為文檔的一種數(shù)據(jù)庫(kù)。文檔數(shù)據(jù)庫(kù)通常以 JSON 或 XML 格式存儲(chǔ)數(shù)據(jù)。
由于文檔數(shù)據(jù)庫(kù)的 no-schema 特性,可以存儲(chǔ)和讀取任意數(shù)據(jù)。
由于使用的數(shù)據(jù)格式是 JSON 或者 BSON,因?yàn)?JSON 數(shù)據(jù)是自描述的,無需在使用前定義字段,讀取一個(gè) JSON 中不存在的字段也不會(huì)導(dǎo)致 SQL 那樣的語法錯(cuò)誤,可以解決關(guān)系型數(shù)據(jù)庫(kù)表結(jié)構(gòu) Schema 擴(kuò)展不方便的問題。
常見文檔數(shù)據(jù)庫(kù)
MongoDB:是一種面向文檔的數(shù)據(jù)庫(kù)管理系統(tǒng),由 C++ 撰寫而成,以此來解決應(yīng)用程序開發(fā)社區(qū)中的大量現(xiàn)實(shí)問題。2007 年 10 月,MongoDB 由 10gen 團(tuán)隊(duì)所發(fā)展。2009 年 2 月首度推出。
CouchDB:Apache CouchDB 是一個(gè)開源數(shù)據(jù)庫(kù),專注于易用性和成為"完全擁抱 Web 的數(shù)據(jù)庫(kù)"。
它是一個(gè)使用 JSON 作為存儲(chǔ)格式,JavaScript 作為查詢語言,MapReduce 和 HTTP 作為 API 的 NoSQL 數(shù)據(jù)庫(kù)。
其中一個(gè)顯著的功能就是多主復(fù)制。CouchDB 的***個(gè)版本發(fā)布在 2005 年,在 2008 年成為了 Apache 的項(xiàng)目。
相關(guān)特性
以 MongoDB 為例進(jìn)行說明,文檔數(shù)據(jù)庫(kù)優(yōu)點(diǎn)如下:
- 新增字段簡(jiǎn)單,無需像關(guān)系型數(shù)據(jù)庫(kù)一樣先執(zhí)行 DDL 語句修改表結(jié)構(gòu),程序代碼直接讀寫即可。
- 容易兼容歷史數(shù)據(jù),對(duì)于歷史數(shù)據(jù),即使沒有新增的字段,也不會(huì)導(dǎo)致錯(cuò)誤,只會(huì)返回空值,此時(shí)代碼兼容處理即可。
- 容易存儲(chǔ)復(fù)雜數(shù)據(jù),JSON 是一種強(qiáng)大的描述語言,能夠描述復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
相比傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù),文檔數(shù)據(jù)庫(kù)的缺點(diǎn)主要是對(duì)多條數(shù)據(jù)記錄的事務(wù)支持較弱,具體體現(xiàn)如下:
- Atomicity(原子性),僅支持單行/文檔級(jí)原子性,不支持多行、多文檔、多語句原子性。
- Solation(隔離性),隔離級(jí)別僅支持已提交讀(Read committed)級(jí)別,可能導(dǎo)致不可重復(fù)讀,幻讀的問題。
- 不支持復(fù)雜查詢,例如 join 查詢,如果需要 join 查詢,需要多次操作數(shù)據(jù)庫(kù)。
MongonDB 還支持多文檔事務(wù)的 Consistency(一致性)和 Durability(持久性),雖然官方宣布 MongoDB 將在 4.0 版本中正式推出多文檔 ACID 事務(wù)支持,***落地情況還有待見證。
使用場(chǎng)景
適用場(chǎng)景:
- 數(shù)據(jù)量很大或者未來會(huì)變得很大。
- 表結(jié)構(gòu)不明確,且字段在不斷增加,例如內(nèi)容管理系統(tǒng),信息管理系統(tǒng)。
不適用場(chǎng)景:
- 在不同的文檔上需要添加事務(wù)。Document-Oriented 數(shù)據(jù)庫(kù)并不支持文檔間的事務(wù)。
- 多個(gè)文檔之間需要復(fù)雜查詢,例如 join。
全文搜索引擎
傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)主要通過索引來達(dá)到快速查詢的目的,在全文搜索的業(yè)務(wù)下,索引也無能為力,主要體現(xiàn)在:
- 全文搜索的條件可以隨意排列組合,如果通過索引來滿足,則索引的數(shù)量非常多。
- 全文搜索的模糊匹配方式,索引無法滿足,只能用 like 查詢,而 like 查詢是整表掃描,效率非常低。
而全文搜索引擎的出現(xiàn),正是解決關(guān)系型數(shù)據(jù)庫(kù)全文搜索功能較弱的問題。
基本原理
全文搜索引擎的技術(shù)原理稱為“倒排索引”(inverted index),是一種索引方法,其基本原理是建立單詞到文檔的索引。與之相對(duì)的是“正排索引”,其基本原理是建立文檔到單詞的索引。
現(xiàn)在有如下文檔集合:
正排索引得到索引如下:
由上可見,正排索引適用于根據(jù)文檔名稱查詢文檔內(nèi)容。簡(jiǎn)單的倒排索引如下:
帶有單詞頻率信息的倒排索引如下:
由上可見,倒排索引適用于根據(jù)關(guān)鍵詞來查詢文檔內(nèi)容。
常見全文搜索引擎
Elasticsearch:是一個(gè)基于 Lucene 的搜索引擎。它提供了一個(gè)分布式,多租戶,能夠全文搜索與發(fā)動(dòng)機(jī) HTTP Web 界面和無架構(gòu) JSON 文件。
Elasticsearch 是用 Java 開發(fā)的,并根據(jù) Apache License 的條款作為開源發(fā)布。
根據(jù) DB-Engines 排名,Elasticsearch 是***的企業(yè)搜索引擎,后面是基于 Lucene 的 Apache Solr。
Solr:是 Apache Lucene 項(xiàng)目的開源企業(yè)搜索平臺(tái)。其主要功能包括全文檢索、***標(biāo)示、分面搜索、動(dòng)態(tài)聚類、數(shù)據(jù)庫(kù)集成,以及富文本(如 Word、PDF)的處理。Solr 是高度可擴(kuò)展的,并提供了分布式搜索和索引復(fù)制。
相關(guān)特性
以 Elasticsearch 為例,全文搜索引擎優(yōu)點(diǎn)如下:
- 查詢效率高,對(duì)海量數(shù)據(jù)進(jìn)行近實(shí)時(shí)的處理。
- 可擴(kuò)展性,基于集群環(huán)境可以方便橫向擴(kuò)展,可以承載 PB 級(jí)數(shù)據(jù)。
- 高可用,Elasticsearch 集群彈性,他們將發(fā)現(xiàn)新的或失敗的節(jié)點(diǎn),重組和重新平衡數(shù)據(jù),確保數(shù)據(jù)是安全的和可訪問的。
缺點(diǎn)如下:
- ACID 支持不足,單一文檔的數(shù)據(jù)是 ACID 的,包含多個(gè)文檔的事務(wù)時(shí)不支持事務(wù)的正?;貪L,支持 I(Isolation)隔離性(基于樂觀鎖機(jī)制的),D(Durability)持久性,不支持 A(Atomicity)原子性,C(Consistency)一致性。
- 對(duì)類似數(shù)據(jù)庫(kù)中通過外鍵的復(fù)雜的多表關(guān)聯(lián)操作支持較弱。
- 讀寫有一定延時(shí),寫入的數(shù)據(jù),最快 1s 中能被檢索到。
- 更新性能較低,底層實(shí)現(xiàn)是先刪數(shù)據(jù),再插入新數(shù)據(jù)。
- 內(nèi)存占用大,因?yàn)?Lucene 將索引部分加載到內(nèi)存中。
使用場(chǎng)景
適用場(chǎng)景如下:
- 分布式的搜索引擎和數(shù)據(jù)分析引擎。
- 全文檢索,結(jié)構(gòu)化檢索,數(shù)據(jù)分析。
- 對(duì)海量數(shù)據(jù)進(jìn)行近實(shí)時(shí)的處理,可以將海量數(shù)據(jù)分散到多臺(tái)服務(wù)器上去存儲(chǔ)和檢索。
不適用場(chǎng)景如下:
- 數(shù)據(jù)需要頻繁更新。
- 需要復(fù)雜關(guān)聯(lián)查詢。
圖形數(shù)據(jù)庫(kù)
圖形數(shù)據(jù)庫(kù)應(yīng)用圖形理論存儲(chǔ)實(shí)體之間的關(guān)系信息。最常見例子就是社會(huì)網(wǎng)絡(luò)中人與人之間的關(guān)系。
關(guān)系型數(shù)據(jù)庫(kù)用于存儲(chǔ)“關(guān)系型”數(shù)據(jù)的效果并不好,其查詢復(fù)雜、緩慢、超出預(yù)期。
而圖形數(shù)據(jù)庫(kù)的獨(dú)特設(shè)計(jì)恰恰彌補(bǔ)了這個(gè)缺陷,解決關(guān)系型數(shù)據(jù)庫(kù)存儲(chǔ)和處理復(fù)雜關(guān)系型數(shù)據(jù)功能較弱的問題。
常見圖形數(shù)據(jù)庫(kù)
Neo4j:是由 Neo4j,Inc. 開發(fā)的圖形數(shù)據(jù)庫(kù)管理系統(tǒng)。由其開發(fā)人員描述為具有原生圖存儲(chǔ)和處理的符合 ACID 的事務(wù)數(shù)據(jù)庫(kù),根據(jù) DB-Engines 排名,Neo4j 是***的圖形數(shù)據(jù)庫(kù)。
ArangoDB:是由 triAGENS GmbH 開發(fā)的原生多模型數(shù)據(jù)庫(kù)系統(tǒng)。數(shù)據(jù)庫(kù)系統(tǒng)支持三個(gè)重要的數(shù)據(jù)模型(鍵/值,文檔,圖形),其中包含一個(gè)數(shù)據(jù)庫(kù)核心和統(tǒng)一查詢語言 AQL(ArangoDB 查詢語言)。
查詢語言是聲明性的,允許在單個(gè)查詢中組合不同的數(shù)據(jù)訪問模式。ArangoDB 是一個(gè) NoSQL 數(shù)據(jù)庫(kù)系統(tǒng),但 AQL 在很多方面與 SQL 類似。
Titan:是一個(gè)可擴(kuò)展的圖形數(shù)據(jù)庫(kù),針對(duì)存儲(chǔ)和查詢包含分布在多機(jī)群集中的數(shù)百億個(gè)頂點(diǎn)和邊緣的圖形進(jìn)行了優(yōu)化。
Titan 是一個(gè)事務(wù)性數(shù)據(jù)庫(kù),可以支持?jǐn)?shù)千個(gè)并發(fā)用戶實(shí)時(shí)執(zhí)行復(fù)雜的圖形遍歷。
相關(guān)特性
以 Neo4j 為例,Neo4j 使用數(shù)據(jù)結(jié)構(gòu)中圖(graph)的概念來進(jìn)行建模。Neo4j 中兩個(gè)最基本的概念是節(jié)點(diǎn)和邊。
節(jié)點(diǎn)表示實(shí)體,邊則表示實(shí)體之間的關(guān)系。節(jié)點(diǎn)和邊都可以有自己的屬性。不同實(shí)體通過各種不同的關(guān)系關(guān)聯(lián)起來,形成復(fù)雜的對(duì)象圖。
針對(duì)關(guān)系數(shù)據(jù),兩種數(shù)據(jù)庫(kù)的存儲(chǔ)結(jié)構(gòu)不同:
Neo4j 中,存儲(chǔ)節(jié)點(diǎn)時(shí)使用了“index-free adjacency”,即每個(gè)節(jié)點(diǎn)都有指向其鄰居節(jié)點(diǎn)的指針,可以讓我們?cè)?O(1) 的時(shí)間內(nèi)找到鄰居節(jié)點(diǎn)。
另外,按照官方的說法,在 Neo4j 中邊是最重要的,即“first-class entities”,所以單獨(dú)存儲(chǔ),這有利于在圖遍歷的時(shí)候提高速度,也可以很方便地以任何方向進(jìn)行遍歷。
優(yōu)點(diǎn)如下:
- 高性能表現(xiàn),圖的遍歷是圖數(shù)據(jù)結(jié)構(gòu)所具有的獨(dú)特算法,即從一個(gè)節(jié)點(diǎn)開始,根據(jù)其連接的關(guān)系,可以快速和方便地找出它的鄰近節(jié)點(diǎn)。
這種查找數(shù)據(jù)的方法并不受數(shù)據(jù)量的大小所影響,因?yàn)猷徑樵兪冀K查找的是有限的局部數(shù)據(jù),不會(huì)對(duì)整個(gè)數(shù)據(jù)庫(kù)進(jìn)行搜索。
- 設(shè)計(jì)的靈活性,數(shù)據(jù)結(jié)構(gòu)的自然伸展特性及其非結(jié)構(gòu)化的數(shù)據(jù)格式,讓圖數(shù)據(jù)庫(kù)設(shè)計(jì)可以具有很大的伸縮性和靈活性。
因?yàn)殡S著需求的變化而增加的節(jié)點(diǎn)、關(guān)系及其屬性并不會(huì)影響到原來數(shù)據(jù)的正常使用。
- 開發(fā)的敏捷性,直觀明了的數(shù)據(jù)模型,從需求的討論開始,到程序開發(fā)和實(shí)現(xiàn),以及最終保存在數(shù)據(jù)庫(kù)中的樣子,它的模樣似乎沒有什么變化,甚至可以說本來就是一模一樣的。
- 完全支持 ACID,不像別的 NoSQL 數(shù)據(jù)庫(kù),Neo4j 還具有完全事務(wù)管理特性,完全支持 ACID 事務(wù)管理。
缺點(diǎn)如下:
- 具有支持節(jié)點(diǎn),關(guān)系和屬性的數(shù)量的限制。
- 不支持拆分。
使用場(chǎng)景
適用場(chǎng)景如下:
- 在一些關(guān)系性強(qiáng)的數(shù)據(jù)中,例如社交網(wǎng)絡(luò)。
- 推薦引擎。如果我們將數(shù)據(jù)以圖的形式表現(xiàn),那么將會(huì)非常有益于推薦的制定。
不適用場(chǎng)景如下:
- 記錄大量基于事件的數(shù)據(jù)(例如日志條目或傳感器數(shù)據(jù))。
- 對(duì)大規(guī)模分布式數(shù)據(jù)進(jìn)行處理,類似于 Hadoop。
- 適合于保存在關(guān)系型數(shù)據(jù)庫(kù)中的結(jié)構(gòu)化數(shù)據(jù)。
- 二進(jìn)制數(shù)據(jù)存儲(chǔ)。
總結(jié)
關(guān)系型數(shù)據(jù)庫(kù)和 NoSQL 數(shù)據(jù)庫(kù)的選型,往往需要考慮幾個(gè)指標(biāo):
- 數(shù)據(jù)量
- 并發(fā)量
- 實(shí)時(shí)性
- 一致性要求
- 讀寫分布和類型
- 安全性
- 運(yùn)維成本
常見軟件系統(tǒng)數(shù)據(jù)庫(kù)選型參考如下:
- 內(nèi)部使用的管理型系統(tǒng),如運(yùn)營(yíng)系統(tǒng),數(shù)據(jù)量少,并發(fā)量小,***考慮關(guān)系型。
- 大流量系統(tǒng),如電商單品頁,后臺(tái)考慮選關(guān)系型,前臺(tái)考慮選內(nèi)存型。
- 日志型系統(tǒng),原始數(shù)據(jù)考慮選列式,日志搜索考慮選倒排索引。
- 搜索型系統(tǒng),例如站內(nèi)搜索,非通用搜索,如商品搜索,后臺(tái)考慮選關(guān)系型,前臺(tái)考慮選倒排索引。
- 事務(wù)型系統(tǒng),如庫(kù)存,交易,記賬,考慮選關(guān)系型+緩存+一致性型協(xié)議。
- 離線計(jì)算,如大量數(shù)據(jù)分析,考慮選列式或者關(guān)系型也可以。
- 實(shí)時(shí)計(jì)算,如實(shí)時(shí)監(jiān)控,可以考慮選內(nèi)存型或者列式數(shù)據(jù)庫(kù)。
在設(shè)計(jì)實(shí)踐中,我們要基于需求、業(yè)務(wù)驅(qū)動(dòng)架構(gòu),無論選用 RDB/NoSQL/DRDB,一定是以需求為導(dǎo)向,最終數(shù)據(jù)存儲(chǔ)方案必然是各種權(quán)衡的綜合性設(shè)計(jì)。
參考資料:
- 從0開始學(xué)架構(gòu) —— Alibaba 李運(yùn)華
- NoSQL漫談
- 圖形數(shù)據(jù)庫(kù) Neo4j 開發(fā)實(shí)戰(zhàn)
- 大數(shù)據(jù)時(shí)代的 9 大Key-Value存儲(chǔ)數(shù)據(jù)庫(kù)
- 事務(wù)—— Redis官方文檔
- MongoDB是如何實(shí)現(xiàn)事務(wù)的ACID?
- MySQL臟讀、虛讀、幻讀
- 全面梳理關(guān)系型數(shù)據(jù)庫(kù)和 NoSQL 的使用情景
- 淺析列式數(shù)據(jù)庫(kù)的特點(diǎn)
- 一分鐘搞懂列式與行式數(shù)據(jù)庫(kù)
- HBase 基本概念
- NoSQL Databases, why we should use, and which one we should choose
- 傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)與分布式數(shù)據(jù)庫(kù)知識(shí)點(diǎn)
陳彩華(caison),主要從事服務(wù)端開發(fā)、需求分析、系統(tǒng)設(shè)計(jì)、優(yōu)化重構(gòu)工作,主要開發(fā)語言是 Java,現(xiàn)任廣州貝聊服務(wù)端研發(fā)工程師。微信號(hào):hua1881375。
【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為51CTO.com】