浅谈常见的NoSQL技术方案和选型
前言
在互聯(lián)網(wǎng)和大數(shù)據(jù)的背景下,越來越多的網(wǎng)站、應(yīng)用系統(tǒng)需要支撐 海量數(shù)據(jù)存儲、高并發(fā)請求、高可用、高可擴(kuò)展性 等特性要求。傳統(tǒng)的 關(guān)系型數(shù)據(jù)庫 已經(jīng)難以應(yīng)對類似的需求,各種各樣的 NoSQL(Not Only SQL)數(shù)據(jù)庫因此而產(chǎn)生。
本文將分析 傳統(tǒng)數(shù)據(jù)庫 的存在的問題,以及幾類 NoSQL 如何解決這些問題。在不同的 業(yè)務(wù)場景 下,作出正確的 數(shù)據(jù)存儲 技術(shù)選型。
正文
1. 傳統(tǒng)數(shù)據(jù)庫缺點(diǎn)
| 大數(shù)據(jù)場景下 I/O 較高 | 因?yàn)閿?shù)據(jù)是按 行存儲,即使只針對其中 某一列 進(jìn)行運(yùn)算,關(guān)系型數(shù)據(jù)庫也會對 整行數(shù)據(jù) 進(jìn)行掃描,從存儲設(shè)備中 讀入內(nèi)存,導(dǎo)致 I/O 較高 |
| 結(jié)構(gòu)化存儲 不夠靈活 | 存儲的是 行記錄,無法存儲 靈活的數(shù)據(jù)結(jié)構(gòu) |
| 表結(jié)構(gòu) schema 擴(kuò)展不方便 | 如要需要修改 表結(jié)構(gòu),需要執(zhí)行執(zhí)行 DDL(data definition language)語句修改,修改期間會導(dǎo)致 鎖表,部分服務(wù)不可用 |
| 全文搜索 功能較弱 | 關(guān)系型數(shù)據(jù)庫只能夠進(jìn)行 子字符串 的 匹配查詢,當(dāng)表的數(shù)據(jù)逐漸變大的時(shí)候,即使在有 索引 的情況下,like 掃表查詢的匹配會 非常慢 |
| 難以 存儲 和 處理 復(fù)雜 關(guān)系型數(shù)據(jù) | 傳統(tǒng)的關(guān)系數(shù)據(jù)庫,并不擅長處理 數(shù)據(jù)點(diǎn)之間 的關(guān)系 |
2. NoSQL簡介
NoSQL,泛指 非關(guān)系型 的數(shù)據(jù)庫,可以理解為 關(guān)系型 數(shù)據(jù)庫的一個(gè)有力補(bǔ)充。
NoSQL 在許多方面性能大大優(yōu)于 非關(guān)系型 數(shù)據(jù)庫的同時(shí),往往也伴隨一些特性的缺失。比較常見的是 事務(wù)功能 的缺失。 數(shù)據(jù)庫事務(wù)正確執(zhí)行的四個(gè)基本要素 ACID 如下:
| A | Atomicity(原子性) | 一個(gè)事務(wù)中的所有操作,要么全部完成,要么全部不完成,不會在中間某個(gè)環(huán)節(jié)結(jié)束。事務(wù)在執(zhí)行過程中發(fā)生錯誤,會被回滾到事務(wù)開始前的狀態(tài),就像這個(gè)事務(wù)從來沒有執(zhí)行過一樣。 |
| C | Consistency一致性 | 在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫的完整性沒有被破壞。 |
| I | Isolation隔離性 | 數(shù)據(jù)庫允許多個(gè)并發(fā)事務(wù)同時(shí)對數(shù)據(jù)進(jìn)行讀寫和修改的能力。隔離性可以防止多個(gè)事務(wù)并發(fā)執(zhí)行時(shí)由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致。 |
| D | Durability持久性 | 事務(wù)處理結(jié)束后,對數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會丟失。 |
針對傳統(tǒng) 關(guān)系型數(shù)據(jù)庫 的不足,下面介紹常見的 5 大類 NoSQL 解決方案:
3. 列式數(shù)據(jù)庫
列式數(shù)據(jù)庫 是以 列相關(guān)存儲架構(gòu) 進(jìn)行數(shù)據(jù)存儲的數(shù)據(jù)庫,主要適合于 批量數(shù)據(jù)處理 和 即時(shí)查詢。相對應(yīng)的是 行式數(shù)據(jù)庫,數(shù)據(jù)以 行相關(guān)的存儲架構(gòu) 進(jìn)行空間分配,主要適合于 小批量 的 數(shù)據(jù)處理,常用于 聯(lián)機(jī)事務(wù)型數(shù)據(jù)處理。
基于列式數(shù)據(jù)庫的 列存儲特性,可以解決某些特定場景下 關(guān)系型數(shù)據(jù)庫 高 I/O 的問題。
3.1. 基本原理
傳統(tǒng)關(guān)系型數(shù)據(jù)庫是 按照行 來存儲數(shù)據(jù)庫,稱為 行式數(shù)據(jù)庫,而 列式數(shù)據(jù)庫 是 按照列 來存儲數(shù)據(jù)。
將表放入存儲系統(tǒng)中有兩種方法,而我們絕大部分是采用 行存儲 的。行存儲法是將 各行 放入 連續(xù)的物理位置,這很像傳統(tǒng)的記錄和文件系統(tǒng)。
列存儲法 是將數(shù)據(jù) 按照列 存儲到數(shù)據(jù)庫中,與 行存儲 類似,下圖是兩種存儲方法的圖形化解釋:
?
3.2. 常見列式數(shù)據(jù)庫
3.2.1. HBase
HBase 是一個(gè)開源的 非關(guān)系型分布式數(shù)據(jù)庫(NoSQL),它參考了 谷歌 的 BigTable 建模,實(shí)現(xiàn)的編程語言為 Java。它是 Apache 軟件基金會的 Hadoop 項(xiàng)目的一部分,運(yùn)行于 HDFS 文件系統(tǒng)之上,為 Hadoop 提供類似于 BigTable 規(guī)模的服務(wù)。因此,它可以 容錯地 存儲 海量稀疏 的數(shù)據(jù)。
?
3.2.2. BigTable
BigTable 是一種 壓縮的、高性能的、高可擴(kuò)展性的,基于 Google 文件系統(tǒng)(Google File System,GFS)的數(shù)據(jù)存儲系統(tǒng),用于存儲 大規(guī)模結(jié)構(gòu)化數(shù)據(jù),適用于云計(jì)算。
?
3.3. 相關(guān)特性
3.3.1. 優(yōu)點(diǎn)
- 高效的儲存空間利用率
列式數(shù)據(jù)庫 針對不同列的 數(shù)據(jù)特征 而發(fā)明了 不同算法,使其比 行式數(shù)據(jù)庫 高的多的 壓縮率。普通的 行式數(shù)據(jù)庫 一般壓縮率在 3:1 到 5:1 左右,而 列式數(shù)據(jù)庫 的壓縮率一般在 8:1 到 30:1 左右。
比較常見的,通過 字典表 壓縮數(shù)據(jù):
?
下面才是那張表本來的樣子。經(jīng)過 字典表 進(jìn)行 數(shù)據(jù)壓縮 后,表中的 字符串 才都變成 數(shù)字。正因?yàn)槊總€(gè)字符串在 字典表 里只 出現(xiàn)了一次,所以達(dá)到了 壓縮 的目的。
- 查詢效率高
讀取多條數(shù)據(jù)的 同一列效率高,因?yàn)檫@些列都是 存儲在一起的,一次磁盤操作可以數(shù)據(jù)的 指定列 全部讀取到 內(nèi)存 中。 下圖通過 一條查詢 的執(zhí)行過程說明 列式存儲 (以及 數(shù)據(jù)壓縮)的優(yōu)點(diǎn)。
?
執(zhí)行步驟如下:
-
適合做聚合操作
-
適合大量的數(shù)據(jù)而不是小數(shù)據(jù)
3.3.2. 缺點(diǎn)
-
不適合掃描 小量數(shù)據(jù)
-
不適合 隨機(jī)的更新
-
不適合做含有刪除和更新的 實(shí)時(shí)操作
-
單行數(shù)據(jù) 支持 ACID 的 事務(wù)操作,多行數(shù)據(jù) 的 事務(wù)操作,不支持事務(wù)的 正常回滾,支持 (Isolation)隔離性、(Durability)持久性,不能保證 (Atomicity)原子性、(Consistency)一致性。
3.4. 應(yīng)用場景
列數(shù)據(jù)庫的適用場景,以 HBase 為例說明:
-
適合 大數(shù)據(jù)量 (100TB 級數(shù)據(jù)),有 快速隨機(jī)訪問 的需求。
-
適合 寫密集型 應(yīng)用,每天寫入量巨大,而 讀數(shù)量相對較小 的應(yīng)用,比如 IM 的 歷史消息,游戲日志 等等。
-
適合不需要 復(fù)雜查詢 條件來查詢數(shù)據(jù)的應(yīng)用。HBase 只支持基于 rowkey 的查詢,對于 HBase 來說,單條記錄 或者 小范圍的查詢 是可以接受的。大范圍 的查詢由于 分布式 的原因,可能在 性能 上有點(diǎn)影響。HBase 不適用于有 join,多級索引,表關(guān)系復(fù)雜 的數(shù)據(jù)模型。
-
對 性能 和 可靠性 要求非常高的應(yīng)用。
-
由于 HBase 本身沒有 單點(diǎn)故障,可用性 非常高。
-
適合 數(shù)據(jù)量較大,而且 增長量 無法預(yù)估的應(yīng)用,需要進(jìn)行優(yōu)雅的數(shù)據(jù)擴(kuò)展的應(yīng)用。HBase 支持 在線擴(kuò)展,即使在一段時(shí)間內(nèi),數(shù)據(jù)量呈 井噴式增長,也可以通過 HBase 橫向擴(kuò)展 來滿足功能。
-
存儲 結(jié)構(gòu)化 和 半結(jié)構(gòu)化 的數(shù)據(jù)。
4. K-V數(shù)據(jù)庫
4.1. 基本概念
指的是使用 鍵值(key-value)存儲的數(shù)據(jù)庫,其數(shù)據(jù)按照 鍵值對 的形式進(jìn)行 組織、索引 和 存儲。
KV 存儲非常適合不涉及過多 數(shù)據(jù)關(guān)系 業(yè)務(wù)的數(shù)據(jù)。它能夠有效減少 讀寫磁盤 的次數(shù),比 SQL 數(shù)據(jù)庫存儲 擁有更好的 讀寫性能,能夠解決 關(guān)系型數(shù)據(jù)庫 無法存儲 數(shù)據(jù)結(jié)構(gòu) 的問題。
4.2. 常見K-V數(shù)據(jù)庫
4.2.1. Redis
Redis 是一個(gè)使用 ANSI C 編寫的 開源、支持網(wǎng)絡(luò)、基于內(nèi)存、可選持久性 的 鍵值對存儲 數(shù)據(jù)庫。Redis 是目前最流行的 鍵值對存儲 數(shù)據(jù)庫之一。
?
4.2.2. Cassandra?[k?'s?ndr?]?
Apache Cassandra(社區(qū)內(nèi)一般簡稱為 C*)是一套 開源的分布式 NoSQL 數(shù)據(jù)庫系統(tǒng)。它最初由 Facebook 開發(fā),用于儲存 收件箱 等簡單格式數(shù)據(jù),集 Google BigTable 的 數(shù)據(jù)模型 與 Amazon Dynamo 的 完全分布式 架構(gòu)于一身。Cassandra 是一種流行的 分布式結(jié)構(gòu)化 數(shù)據(jù)存儲方案。
?
4.2.3. Memcached
Memcached 是一個(gè) 開放源代碼、高性能、分配的 內(nèi)存對象緩存系統(tǒng)。用于加速動態(tài) web 應(yīng)用程序,減輕關(guān)系型數(shù)據(jù)庫負(fù)載。它可以應(yīng)對 任意多個(gè)連接,使用 非阻塞的網(wǎng)絡(luò) IO。由于它的工作機(jī)制是在內(nèi)存中開辟一塊空間,然后建立一個(gè) Hash 表,Memcached 自管理這些 Hash 表。
Memcached 簡單而強(qiáng)大。它簡單的設(shè)計(jì)促進(jìn) 迅速部署,易于發(fā)現(xiàn)所面臨的問題,解決了很多 大型數(shù)據(jù)緩存。
image
4.2.4. LevelDB
LevelDB 是一個(gè)由 Google 所研發(fā)的 鍵/值對(Key/Value Pair)嵌入式 數(shù)據(jù)庫管理系統(tǒng) 編程庫,以開源的 BSD 許可證發(fā)布。
?
4.3. 相關(guān)特性
K-V 數(shù)據(jù)庫的相關(guān)特性,以 Redis 為例說明:
4.3.1. 優(yōu)點(diǎn)
- 性能極高
Redis 單機(jī)最高能支持超過 10W 的 TPS。
- 豐富的數(shù)據(jù)類型
Redis 支持包括 String,Hash,List,Set,Sorted Set,Bitmap 和 Hyperloglog 等數(shù)據(jù)結(jié)構(gòu)。
- 豐富的特性
Redis 還支持 publish/subscribe,通知,key 過期 等特性。
4.3.2. 缺點(diǎn)
- Redis 事務(wù) 不能支持 原子性 和 持久性(A 和 D),只支持 隔離性 和 一致性(I 和 C)。
這里所說的 無法保證原子性,是針對 Redis 的 事務(wù)操作,因?yàn)槭聞?wù)是 不支持回滾(roll back),而因?yàn)?Redis 的 單線程模型,Redis 的普通操作是 原子性的。
4.4 應(yīng)用場景
4.4.1. 適用場景
- 適合存儲 用戶信息(比如 會話)、配置文件、參數(shù)、購物車 等等。這些信息一般都和 ID 掛鉤。
4.4.2. 不適用場景
-
不適合需要通過 值 來查詢,而不是 鍵 來查詢。Key-Value 數(shù)據(jù)庫中根本沒有通過 值查詢 的途徑。
-
不適合需要儲存 數(shù)據(jù)之間的關(guān)系。在 Key-Value 數(shù)據(jù)庫中不能通過 兩個(gè)或以上 的鍵來 關(guān)聯(lián)數(shù)據(jù)。
-
不適合需要支持 事務(wù) 的場景。在 Key-Value 數(shù)據(jù)庫中 故障產(chǎn)生 時(shí)不可以進(jìn)行 回滾。
5. 文檔型數(shù)據(jù)庫
5.1. 基本概念
文檔數(shù)據(jù)庫 用于將 半結(jié)構(gòu)化數(shù)據(jù) 存儲為 文檔 的一種數(shù)據(jù)庫。文檔數(shù)據(jù)庫通常以 JSON 或 XML 格式存儲數(shù)據(jù)。
-
由于文檔數(shù)據(jù)庫的 no-schema 特性,可以 存儲 和 讀取 任意數(shù)據(jù)。
-
由于使用的 數(shù)據(jù)格式 是 JSON 或者 BSON,因?yàn)?JSON 數(shù)據(jù)是 自描述的,無需在使用前定義字段,讀取一個(gè) JSON 中 不存在的字段 也不會導(dǎo)致 SQL 那樣的語法錯誤,可以解決關(guān)系型數(shù)據(jù)庫 表結(jié)構(gòu) schema 擴(kuò)展不方便 的問題。
5.2. 常見文檔數(shù)據(jù)庫
5.2.1. MongoDB
MongoDB 是一個(gè)基于 分布式文件存儲 的數(shù)據(jù)庫。由 C++ 語言編寫。旨在為 WEB 應(yīng)用提供可擴(kuò)展的 高性能 數(shù)據(jù)存儲解決方案。
MongoDB 是一個(gè)介于 關(guān)系數(shù)據(jù)庫 和 非關(guān)系數(shù)據(jù)庫 之間的產(chǎn)品,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能 最豐富,最像關(guān)系數(shù)據(jù)庫的 NoSQL。
?
5.2.2. CouchDB
CouchDB 是用 Erlang 開發(fā)的 面向文檔 的 分布式 數(shù)據(jù)庫,用于存儲 半結(jié)構(gòu)化 的數(shù)據(jù),比較類似 lucene 的 index 結(jié)構(gòu)。
CouchDB 支持 RESTful API,它使用 JSON 作為 存儲格式,JavaScript 作為 查詢語言,MapReduce 和 HTTP 作為 API 的 NoSQL 數(shù)據(jù)庫。其中一個(gè)顯著的功能就是 多主復(fù)制 功能。除此之外,CouchDB 構(gòu)建在強(qiáng)大的 B- 樹儲存引擎 之上。
[圖片上傳失敗...(image-fe7dcf-1536933787428)]
5.3. 相關(guān)特性
文檔型數(shù)據(jù)庫 的相關(guān)特性,以 MongoDB 為例進(jìn)行說明:
5.3.1. 優(yōu)點(diǎn)
-
新增字段簡單不需要像關(guān)系型數(shù)據(jù)庫一樣,先執(zhí)行 DDL 語句 修改表結(jié)構(gòu),程序代碼 直接讀寫 即可。
-
容易兼容 歷史數(shù)據(jù)。對于歷史數(shù)據(jù),即使沒有新增的字段,也不會導(dǎo)致錯誤,只會返回 空值,此時(shí) 代碼兼容處理 即可。
-
容易存儲復(fù)雜數(shù)據(jù)。JSON 是一種強(qiáng)大的 描述語言,能夠描述復(fù)雜的 數(shù)據(jù)結(jié)構(gòu)。
5.3.2. 缺點(diǎn)
相比 傳統(tǒng)關(guān)系型數(shù)據(jù)庫,文檔數(shù)據(jù)庫的缺點(diǎn),主要是對 多條數(shù)據(jù)記錄 的 事務(wù)支持較弱,具體體現(xiàn)如下:
-
Atomicity(原子性):僅支持 單行/文檔級原子性,不支持 多行、多文檔、多語句原子性。
-
Isolation(隔離性):隔離級別僅支持 已提交讀(Read committed)級別,可能導(dǎo)致 不可重復(fù)讀,幻讀 的問題。
-
不支持 復(fù)雜查詢。例如 join 查詢,如果需要 join 查詢,需要 多次操作數(shù)據(jù)庫。
5.4. 應(yīng)用場景
5.4.1. 適用場景
-
數(shù)據(jù)量 很大或者未來會變得很大。
-
表結(jié)構(gòu)不明確,且 字段 在 不斷增加,例如內(nèi)容管理系統(tǒng),信息管理系統(tǒng)。
5.4.2. 不適用場景
-
在不同的文檔上需要添加 事務(wù)。Document-Oriented 數(shù)據(jù)庫并不支持 文檔間的事務(wù)。
-
多個(gè)文檔之間需要 復(fù)雜的查詢,例如 join 操作。
6. 全文搜索引擎
6.1. 基本概念
傳統(tǒng)關(guān)系型數(shù)據(jù)庫,主要通過 索引 來達(dá)到 快速查詢 的目的。在 全文搜索 的業(yè)務(wù)下,索引 也無能為力,主要體現(xiàn)在以下幾方面:
-
全文搜索的條件,可以隨意 排列組合,如果通過索引來滿足,則索引的 數(shù)量非常多。
-
全文搜索的 模糊匹配方式,索引 無法滿足,只能用 like 進(jìn)行查詢,而 like 查詢是 整表掃描,效率非常低。
全文搜索引擎的出現(xiàn),正是解決關(guān)系型數(shù)據(jù)庫 全文搜索較弱 的問題。
6.2. 基本原理
全文搜索引擎 的技術(shù)原理稱為 倒排索引(inverted index),是一種 索引方法,其基本原理是建立 單詞 到 文檔 的索引。與之相對是,是 正排索引,其基本原理是建立 文檔 到 單詞 的索引。
- 現(xiàn)在有如下文檔集合:
[圖片上傳失敗...(image-695617-1536933787428)]
- 正排索引 得到索引如下:
[圖片上傳失敗...(image-35c3a2-1536933787428)]
可見,正排索引 適用于根據(jù) 文檔名稱 查詢 文檔內(nèi)容。
- 簡單的 倒排索引 如下:
image
- 帶有 單詞頻率 信息的 倒排索引 如下:
image
可見,倒排索引 適用于根據(jù) 關(guān)鍵詞 來查詢 文檔內(nèi)容。
6.3. 常見全文搜索引擎
6.3.1. ElasticSearch
ElasticSearch 是一個(gè)基于 Apache Lucene 的 搜索引擎。它提供了一個(gè) 分布式,多租戶 對全文搜索引擎。ElasticSearch 是用 Java 開發(fā)的,對外提供 RESTful Web 接口。根據(jù) DB-Engines 排名,ElasticSearch 是最受歡迎的 企業(yè)搜索引擎。
image
6.3.2. Solr
Solr 是 Apache Lucene 項(xiàng)目的 開源企業(yè)搜索平臺。其主要功能包括 全文檢索、命中標(biāo)示、分面搜索、動態(tài)聚類、數(shù)據(jù)庫集成,以及 富文本(比如 Word、PDF)處理等等。Solr 是高度 可擴(kuò)展 的,并提供了 分布式搜索 和 索引復(fù)制。
image
6.4. 相關(guān)特性
全文搜索引擎,以 ElasticSearch 為例說明:
6.4.1. 優(yōu)點(diǎn)
-
查詢效率高,適用于對 海量數(shù)據(jù) 進(jìn)行 近實(shí)時(shí) 的處理。
-
可擴(kuò)展性
-
基于 集群 環(huán)境可以方便 橫向擴(kuò)展,可以承載 PB 級的數(shù)據(jù)。
-
支持 高可用,ElasticSearch 集群彈性靈活,可以發(fā)現(xiàn)新的或失敗的節(jié)點(diǎn),重組 和 重新平衡 數(shù)據(jù),確保數(shù)據(jù)是 安全 和 可訪問的。
6.4.2. 缺點(diǎn)
-
事務(wù)的 ACID 支持不足,單一文檔 的數(shù)據(jù)是支持 ACID 的。對于 多個(gè)文檔 的 事務(wù)操作,不支持事務(wù)的 正常回滾。支持(Isolation)隔離性(基于 樂觀鎖機(jī)制)和(Durability)持久性,不支持(Atomicity)原子性,(Consistency)一致性。
-
對類似數(shù)據(jù)庫中,通過 外鍵 進(jìn)行 多表關(guān)聯(lián)的復(fù)雜操作支持較弱。
-
讀寫 有一定 延時(shí),寫入的數(shù)據(jù),最快 1s 中能被檢索到。
-
更新 性能較低,底層實(shí)現(xiàn)是 先刪數(shù)據(jù),再 插入新數(shù)據(jù)。
-
內(nèi)存占用大,因?yàn)?Lucene 將 索引部分 加載到 內(nèi)存 中。
6.5. 應(yīng)用場景
6.5.1. 適用場景
- 分布式的 搜索引擎 和 數(shù)據(jù)分析引擎。
- 全文檢索,結(jié)構(gòu)化檢索 以及 數(shù)據(jù)分析。
- 對海量數(shù)據(jù)進(jìn)行 近實(shí)時(shí) 的處理,可以將 海量數(shù)據(jù) 分散到 多臺服務(wù)器 上去 存儲 和 檢索。
6.5.2. 不適用場景
-
數(shù)據(jù)需要 頻繁更新。
-
需要 復(fù)雜關(guān)聯(lián)查詢。
7. 圖形數(shù)據(jù)庫
7.1. 基本概念
圖形數(shù)據(jù)庫 應(yīng)用 圖形理論 存儲 實(shí)體 之間的 關(guān)系信息。最常見例子就是 社會網(wǎng)絡(luò)中人與人之間的關(guān)系。關(guān)系型數(shù)據(jù)庫 用于存儲這種 關(guān)系型數(shù)據(jù) 的效果并不好,其查詢 復(fù)雜、緩慢、超出預(yù)期。
圖形數(shù)據(jù)庫 的獨(dú)特設(shè)計(jì)彌補(bǔ)了這個(gè)缺陷,解決 關(guān)系型 數(shù)據(jù)庫 存儲 和 處理復(fù)雜關(guān)系型數(shù)據(jù) 功能較弱的問題。
7.2. 常見圖形數(shù)據(jù)庫
7.2.1. Neo4j
Neo4j 是一個(gè) 高性能的,NOSQL 圖形數(shù)據(jù)庫,它將 結(jié)構(gòu)化數(shù)據(jù) 存儲在 “圖形網(wǎng)絡(luò)上” 而不是 “表中”。它是一個(gè) 嵌入式的、基于磁盤的、具備完全的 事務(wù)特性 的 Java 持久化引擎。
Neo4j 也可以被看作是一個(gè) 高性能的圖引擎。程序員工作在一個(gè) 面向?qū)ο蟮?/strong>、靈活的網(wǎng)絡(luò)結(jié)構(gòu) 下而不是 嚴(yán)格、靜態(tài) 的 表中。
image
7.2.2. ArangoDB
ArangoDB 是一個(gè) 原生多模型 數(shù)據(jù)庫系統(tǒng)。數(shù)據(jù)庫系統(tǒng)支持 三個(gè) 重要的 數(shù)據(jù)模型(鍵/值,文檔,圖形)。
ArangoDB 包含一個(gè) 數(shù)據(jù)庫核心 和 統(tǒng)一查詢語言 AQL(ArangoDB 查詢語言)。查詢語言是 聲明性的,允許在 單個(gè)查詢 中 組合 不同的 數(shù)據(jù)訪問模式。ArangoDB 是一個(gè) NoSQL 數(shù)據(jù)庫系統(tǒng),但 AQL 在很多方面與 SQL 都類似。
image
7.3. 基本原理
圖形數(shù)據(jù)庫,以 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ù)雜的 對象圖。
針對關(guān)系數(shù)據(jù),兩種數(shù)據(jù)庫的 存儲結(jié)構(gòu) 分別如下:
image
在 Neo4j 中,存儲節(jié)點(diǎn) 時(shí)使用了 index-free adjacency,即 每個(gè)節(jié)點(diǎn) 都有指向其 鄰居節(jié)點(diǎn) 的 指針。這樣就可以在 O(1) 的 復(fù)雜度 內(nèi)找到 鄰居節(jié)點(diǎn)。另外,按照官方的說法,在 Neo4j 中 邊 s是最重要的,是 first-class entities,需要 單獨(dú)存儲。這有利于在 圖遍歷 的時(shí)候 提高速度,也可以很方便地以 任何方向 進(jìn)行遍歷。
image
7.4. 相關(guān)特性
7.4.1. 優(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)?鄰近查詢 始終查找的是 有限的局部數(shù)據(jù),不會對 整個(gè)數(shù)據(jù)庫 進(jìn)行搜索。
- 設(shè)計(jì)的靈活性
數(shù)據(jù)結(jié)構(gòu) 的自然伸展特性,以及其 非結(jié)構(gòu)化 的 數(shù)據(jù)格式,讓圖數(shù)據(jù)庫設(shè)計(jì)可以具有很大的 伸縮性 和 靈活性。因?yàn)殡S著需求的變化而增加的 節(jié)點(diǎn)、關(guān)系 及其 屬性,并不會影響到 原來數(shù)據(jù) 的正常使用。
- 開發(fā)的敏捷性
數(shù)據(jù)模型 直接明了,從需求的討論開始,到程序開發(fā)和實(shí)現(xiàn),基本上不會有大的變化。
- 完全支持ACID
不像別的 NoSQL 數(shù)據(jù)庫,Neo4j 還完全具有 事務(wù)管理特性,完全支持 ACID 事務(wù)管理。
7.4.2. 缺點(diǎn)
-
節(jié)點(diǎn),關(guān)系 和它們的 屬性 的數(shù)量被 限制。
-
不支持 拆分。
7.5. 應(yīng)用場景
7.5.1. 適用場景
-
在一些 關(guān)系性強(qiáng) 的數(shù)據(jù)應(yīng)用,例如 社交網(wǎng)絡(luò)。
-
推薦引擎,將數(shù)據(jù)以 圖的形式 表現(xiàn),非常有益于推薦的制定。
7.5.2. 不適用場景
-
記錄大量 基于事件 的數(shù)據(jù),如日志記錄、傳感器數(shù)據(jù)。
-
對大規(guī)模 分布式數(shù)據(jù) 進(jìn)行處理,類似于 Hadoop。
-
不適用于應(yīng)該保存在 關(guān)系型數(shù)據(jù)庫 中的 結(jié)構(gòu)化數(shù)據(jù)。
-
二進(jìn)制數(shù)據(jù)存儲。
小結(jié)
關(guān)于 關(guān)系型數(shù)據(jù)庫 和 NoSQL 數(shù)據(jù)庫 的選型,往往需要考慮幾個(gè)指標(biāo):
- 數(shù)據(jù)量
- 并發(fā)量
- 實(shí)時(shí)性
- 一致性要求
- 讀寫分布
- 數(shù)據(jù)類型
- 安全性
- 運(yùn)維成本
常見的系統(tǒng)數(shù)據(jù)庫選型參考如下:
| 企業(yè)內(nèi)部管理系統(tǒng) | 例如運(yùn)營系統(tǒng),數(shù)據(jù)量少,并發(fā)量小,首選考慮 關(guān)系型數(shù)據(jù)庫 |
| 互聯(lián)網(wǎng)大流量系統(tǒng) | 例如電商單品頁,后臺考慮選 關(guān)系型數(shù)據(jù)庫,前臺考慮選 內(nèi)存型數(shù)據(jù)庫 |
| 日志型系統(tǒng) | 原始數(shù)據(jù) 考慮選 列式數(shù)據(jù)庫,日志搜索 考慮選 倒排索引 |
| 搜索型系統(tǒng) | 例如站內(nèi)搜索,非通用搜索,商品搜索,后臺考慮選 關(guān)系型數(shù)據(jù)庫,前臺考慮選 倒排索引 |
| 事務(wù)型系統(tǒng) | 例如庫存管理,交易,記賬,考慮選 關(guān)系型數(shù)據(jù)庫 + 緩存數(shù)據(jù)庫 + 一致性型協(xié)議 |
| 離線計(jì)算 | 例如大量數(shù)據(jù)分析,考慮選 列式數(shù)據(jù)庫 或者 關(guān)系型數(shù)據(jù)庫 都可以 |
| 實(shí)時(shí)計(jì)算 | 例如實(shí)時(shí)監(jiān)控,可以考慮選 內(nèi)存型數(shù)據(jù)庫 或者 列式數(shù)據(jù)庫 |
設(shè)計(jì)實(shí)踐中,要基于需求、業(yè)務(wù)驅(qū)動架構(gòu),無論選用 RDB/NoSQL/DRDB。一定是以需求為導(dǎo)向,最終數(shù)據(jù)存儲方案,必然是考慮各種 權(quán)衡 的綜合性設(shè)計(jì)。
歡迎關(guān)注技術(shù)公眾號: 零壹技術(shù)棧
零壹技術(shù)棧
本帳號將持續(xù)分享后端技術(shù)干貨,包括虛擬機(jī)基礎(chǔ),多線程編程,高性能框架,異步、緩存和消息中間件,分布式和微服務(wù),架構(gòu)學(xué)習(xí)和進(jìn)階等學(xué)習(xí)資料和文章。
作者:零壹技術(shù)棧
鏈接:https://www.jianshu.com/p/a586a8bf13f7
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
總結(jié)
以上是生活随笔為你收集整理的浅谈常见的NoSQL技术方案和选型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 宁德时代首席科学家:锂矿全球供给足够 涨
- 下一篇: 《生化危机2/3/7》PC版太拉垮 卡普