來源:北大青鳥總部 2023年04月04日 15:42
傳統(tǒng)數(shù)據(jù)庫(kù)如Mysql、Oracle的出現(xiàn)解決了早期互聯(lián)網(wǎng)對(duì)于數(shù)據(jù)存儲(chǔ)、數(shù)據(jù)一致性的問題,但隨著互聯(lián)網(wǎng)、物聯(lián)網(wǎng)的快速發(fā)展而導(dǎo)致對(duì)數(shù)據(jù)存儲(chǔ)的要求不只是數(shù)據(jù)一致性,還有了更多特性需求。
傳統(tǒng)數(shù)據(jù)庫(kù)有幾個(gè)缺點(diǎn):在大數(shù)據(jù)場(chǎng)景下讀取IO較高、無法存儲(chǔ)靈活的數(shù)據(jù)結(jié)構(gòu)、表結(jié)構(gòu)擴(kuò)展不方便、全文搜索功能較弱(使用索引效率低)、不擅長(zhǎng)出復(fù)雜關(guān)系型數(shù)據(jù)庫(kù),因此非關(guān)系型數(shù)據(jù)庫(kù)NoSQL是極好的解決方案。
作為關(guān)系型數(shù)據(jù)庫(kù)的補(bǔ)充,再根據(jù)互聯(lián)網(wǎng)時(shí)代的需求不同,NoSQL可以分為:
支持高性能并發(fā)讀寫的Key-Value數(shù)據(jù)庫(kù),如Redis;
支持海量數(shù)據(jù)訪問的文檔數(shù)據(jù)庫(kù),如MongoDB、CouchDB;
支持大數(shù)據(jù)存儲(chǔ)和分析的列式數(shù)據(jù)庫(kù),如HBase;
支持全文搜索的搜索引擎數(shù)據(jù)庫(kù),如ElasticSearch。
Key-Value數(shù)據(jù)庫(kù)
所謂KV數(shù)據(jù)庫(kù)就是按照鍵值對(duì)進(jìn)行存儲(chǔ)的數(shù)據(jù)庫(kù),key是數(shù)據(jù)的標(biāo)識(shí),value是數(shù)據(jù)的值。Redis是典型的KV數(shù)據(jù)庫(kù),可以存儲(chǔ)string、hash、list、set等數(shù)據(jù)結(jié)構(gòu)。
我們以微博清除歷史粉絲為例,對(duì)于redis來說,只要使用RPOPkey從隊(duì)列的右邊出隊(duì)一個(gè)元素就可以了。是不是很簡(jiǎn)單?
但如果是關(guān)系數(shù)據(jù)庫(kù)就比較復(fù)雜了,因?yàn)殛P(guān)系型數(shù)據(jù)庫(kù)是行式存儲(chǔ),所以在建表時(shí)每條數(shù)據(jù)除了有數(shù)字編號(hào)之外,還有位置編號(hào),用于判斷數(shù)據(jù)是否第一條,其次通過sql語句找到了第一條數(shù)據(jù)之后,再次執(zhí)行sql刪除語句,最后更新從第二條開始的所有數(shù)據(jù)的位置編號(hào)??梢钥吹疥P(guān)系型數(shù)據(jù)庫(kù)需要進(jìn)行多次SQL操作,實(shí)現(xiàn)非常麻煩,效率低,性能低。
Redis數(shù)據(jù)庫(kù)的主要缺點(diǎn)是不支持完整的ACID事務(wù),但其實(shí)大部分業(yè)務(wù)也不需要嚴(yán)格遵守ACID原則,比如剛剛的微博粉絲案例,少一個(gè)或多一個(gè)粉絲對(duì)于我們并沒有什么影響。
文檔數(shù)據(jù)庫(kù)
所謂文檔數(shù)據(jù)庫(kù)就是可以存儲(chǔ)和讀取任意的數(shù)據(jù),在使用之前不需要定義字段,讀取某個(gè)不存在的字段也不會(huì)報(bào)錯(cuò),目前大部分文檔數(shù)據(jù)庫(kù)存儲(chǔ)的數(shù)據(jù)格式是JSON,可以支持比較復(fù)雜的數(shù)據(jù)結(jié)構(gòu),MongoDB是典型的文檔數(shù)據(jù)庫(kù)。比如一個(gè)商品信息管理系統(tǒng),商品的信息有商品ID、生產(chǎn)日期、品牌、貨號(hào)、口味、包裝方式、凈含量、產(chǎn)地、生產(chǎn)許可證編號(hào)、廠名、配料表、存儲(chǔ)方法、保質(zhì)期、食品添加劑。其中口味是一個(gè)列表(因?yàn)榭谖犊梢杂卸鄠€(gè)),產(chǎn)地是一個(gè)結(jié)構(gòu)(包含省市區(qū)具體地址),保質(zhì)期包含包裝方式、生產(chǎn)日期、存儲(chǔ)時(shí)長(zhǎng)等。如果使用文檔數(shù)據(jù)庫(kù),一個(gè)JSON就可以完全描述。
如果使用關(guān)系型數(shù)據(jù)庫(kù),則需要設(shè)計(jì)多張表并且關(guān)聯(lián)起來,包含基本信息(有商品ID、價(jià)格、品牌三列)、地址(有省份、市區(qū)、鄉(xiāng)鎮(zhèn)、小區(qū)、門牌號(hào)四列)、配料表(有雞蛋、面粉、食鹽、添加劑等多列),表創(chuàng)建后再使用Join將所有的內(nèi)容關(guān)聯(lián)起來,最終形成一個(gè)商品信息提供給到用戶。
文檔數(shù)據(jù)庫(kù)有兩個(gè)缺點(diǎn)。
缺點(diǎn)之一是不支持事務(wù)操作,比如使用MongoDB來存儲(chǔ)商品庫(kù)存,用戶付款、減庫(kù)存屬于一個(gè)事務(wù)操作,用關(guān)系型數(shù)據(jù)庫(kù)就很簡(jiǎn)單,如果使用MongoDB來實(shí)現(xiàn),就可能出現(xiàn)庫(kù)存減了但是用戶沒有付款的情況。
缺點(diǎn)之二是不支持join操作,比如我們想查詢購(gòu)買了陳克明面條中的女性用戶,使用關(guān)系型數(shù)據(jù)庫(kù),將用戶信息表和訂單表通過用戶ID來join操作就可以了,如果使用MongoDB,則需要查詢訂單表中買了陳克明面條的用戶,再查詢用戶中的女性用戶。
列式數(shù)據(jù)庫(kù)
所謂列式數(shù)據(jù)庫(kù)就是按照列來存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)庫(kù),傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)是按行來存儲(chǔ)在磁盤,即行式數(shù)據(jù)庫(kù),典型的列式數(shù)據(jù)庫(kù)是HBase。怎么理解行式和列式存儲(chǔ)呢?
以某個(gè)用戶信息登記表來說,按行存儲(chǔ)是二維表格中的每一行占據(jù)一塊連續(xù)的存儲(chǔ)空間,按列存儲(chǔ)則是每一列占據(jù)一塊連續(xù)的存儲(chǔ)空間。所以列式存儲(chǔ)數(shù)據(jù)庫(kù)非常適合大數(shù)據(jù)分析場(chǎng)景。
比如我們想分析某個(gè)區(qū)域的平均身高和體重,在mysql數(shù)據(jù)庫(kù)中需要獲取到每行的身高、體重?cái)?shù)據(jù),再來求平均,如果有10000個(gè)人,就需要請(qǐng)求磁盤空間10000次;在hbase數(shù)據(jù)庫(kù)中我們只需要請(qǐng)求兩次,獲取身高和體重這一列的數(shù)據(jù)求平均即可。
中期的時(shí)候是敏捷開發(fā)模型。因?yàn)榛ヂ?lián)網(wǎng)上涌入的網(wǎng)民開始增多,大家的關(guān)注點(diǎn)開始變成好用、好玩,而此時(shí)一些有遠(yuǎn)見的人開始注意到互聯(lián)網(wǎng)紅利,投身于互聯(lián)網(wǎng),此時(shí)的開發(fā)模式演變成了敏捷開發(fā)模型。
敏捷開發(fā)模型面對(duì)的是頻繁的需求變化,要求快速開發(fā)。比較流行的實(shí)際案例則是Scrum、XP極限編程。在新迭代(一般2-6周)開始前,產(chǎn)品經(jīng)理將需求拆分成具體的開發(fā)任務(wù),研發(fā)人員進(jìn)行任務(wù)認(rèn)領(lǐng),每日站會(huì)進(jìn)行任務(wù)的review,直到開發(fā)完成,發(fā)布新的可用版本。
列式數(shù)據(jù)庫(kù)的缺點(diǎn)就是不適合小量數(shù)據(jù)、不適合隨機(jī)的更新數(shù)據(jù)、不適合有刪除和更新的實(shí)時(shí)操作、不適合ACID事務(wù),因?yàn)榱惺酱鎯?chǔ)中要隨機(jī)的去更新數(shù)據(jù)或刪除某條數(shù)據(jù),比較耗費(fèi)磁盤IO,影響整體的性能。
搜索引擎數(shù)據(jù)庫(kù)
所謂搜索引擎數(shù)據(jù)庫(kù)就是支持在數(shù)據(jù)庫(kù)內(nèi)通過關(guān)鍵字全文檢索,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)是通過索引,比如like、where等語句來達(dá)到快速查詢,在全文檢索的情況下,需要整個(gè)表掃描,效率非常低。ElasticSearch是典型的全文搜索引擎數(shù)據(jù)庫(kù),采用倒排索引的模式,建立從單詞到文檔的索引關(guān)系。比如現(xiàn)在我們有這樣的一個(gè)文檔集合,按單詞將文檔內(nèi)容進(jìn)行拆分,如文檔1-谷歌地圖之父跳槽Facebook,可拆分成單詞谷歌(單詞ID為1)、地圖(單詞ID為2)、之父(單詞ID為3)、跳槽(單詞ID為4)、Facebook(單詞ID為5),其余的依次拆分可得到如下的倒排索引表….
通過關(guān)鍵字就可以檢索文章了,我們?cè)跀?shù)據(jù)庫(kù)搜索谷歌時(shí),所有的結(jié)果都會(huì)返回,搜索創(chuàng)始人時(shí)則只返回“谷歌地圖創(chuàng)始人拉斯離開谷歌加盟Facebook”。
SQL與NoSQL在是隨著互聯(lián)網(wǎng)的發(fā)展衍生的不同產(chǎn)物,在某一類業(yè)務(wù)的處理上都有自己的強(qiáng)項(xiàng),在本文中我們介紹了四種類型的非關(guān)系型數(shù)據(jù)庫(kù),你清楚了NoSQL哪些地方強(qiáng)了嘛?而在業(yè)務(wù)中,我們將SQL與NoSQL結(jié)合,取長(zhǎng)補(bǔ)短,賦能業(yè)務(wù)即可~