關系數據庫
關(guan)系數據(ju)(ju)庫(Relational Database)是建(jian)立在關(guan)系模(mo)型(xing)(xing)基(ji)礎(chu)上(shang)的(de)數據(ju)(ju)庫,借(jie)助于幾何代數等(deng)(deng)數學概念(nian)和方(fang)法(fa)來處理數據(ju)(ju)庫中的(de)數據(ju)(ju)。所謂關(guan)系模(mo)型(xing)(xing)是一對一、一對多或者多對多等(deng)(deng)關(guan)系,常見的(de)關(guan)系型(xing)(xing)數據(ju)(ju)庫有 Oracle、SQL Server、DB2、MySQL 等(deng)(deng)。
而文檔型(xing)數(shu)(shu)據(ju)(ju)庫(ku)是(shi)一種非關(guan)系(xi)型(xing)數(shu)(shu)據(ju)(ju)庫(ku),非關(guan)系(xi)型(xing)數(shu)(shu)據(ju)(ju)庫(ku)(Not Only SQL,NoSQL)正好與關(guan)系(xi)型(xing)數(shu)(shu)據(ju)(ju)庫(ku)相反,它不是(shi)建立(li)在(zai)“關(guan)系(xi)模型(xing)”上的(de)數(shu)(shu)據(ju)(ju)庫(ku)。文檔型(xing)數(shu)(shu)據(ju)(ju)庫(ku)的(de)典型(xing)代(dai)表是(shi) MongoDB。
ACID特性
關系(xi)型數(shu)(shu)據庫(ku)屬于(yu)早期的(de)(de)傳統型數(shu)(shu)據庫(ku),它有(you)著標準化的(de)(de)數(shu)(shu)據模型,以及事務(wu)和(he)持(chi)久化的(de)(de)支持(chi)、例如(ru),關系(xi)型數(shu)(shu)據庫(ku)都會支持(chi)的(de)(de) ACID 特性(xing)(xing),也就是(shi)原子(zi)性(xing)(xing)(Atomicity)、一致性(xing)(xing)(Consistency)、隔(ge)離(li)性(xing)(xing)(Isolation)和(he)持(chi)久性(xing)(xing)(Durability),具體(ti)含義如(ru)下。
原子性(Atomicity):是指(zhi)一個事(shi)務中的所有操(cao)作,要么全(quan)部完(wan)成(cheng)、要么全(quan)部不(bu)完(wan)成(cheng),不(bu)會存(cun)在中間的狀(zhuang)態(tai)。也就是說(shuo)事(shi)務在正常的情(qing)況(kuang)下會執行完(wan)成(cheng);異常的情(qing)況(kuang)下,比如在執行的過程中如果出現問(wen)題,會回(hui)滾成(cheng)最初的狀(zhuang)態(tai),而非中間狀(zhuang)態(tai)。
一致性(Consistency):是指事(shi)務(wu)(wu)從開(kai)始執行到結束執行之(zhi)間的(de)中間狀態(tai)不會被(bei)其他事(shi)務(wu)(wu)看到。
隔離(li)性(Isolation):是指(zhi)數據庫(ku)允(yun)許(xu)多個事務(wu)同時(shi)對(dui)數據進行讀寫(xie)或修改的能力(li),并(bing)且整個過(guo)程(cheng)對(dui)各個事務(wu)來說是相互(hu)隔離(li)的。
持久性(Durability):是(shi)指每次(ci)事務提交之后(hou)都(dou)不會丟(diu)失。
關系數據庫的三范式
關(guan)系(xi)型數據庫一(yi)般(ban)遵(zun)循三范式設(she)計思想,具體內容(rong)如(ru)下。
第一范(fan)式(The First Normal Form,1NF):要求(qiu)對屬性的原子性,也就(jiu)是(shi)說要求(qiu)數據庫(ku)中的字段(duan)需要具備原子性,不(bu)能(neng)再被拆分。比如(ru),用戶表中有(you)字段(duan):用戶 ID、用戶名、電(dian)話(hua);而(er)其中電(dian)話(hua)又可以分為(wei):家(jia)庭電(dian)話(hua)和移動(dong)電(dian)話(hua)等。因此(ci),此(ci)表不(bu)符合第一范(fan)式,如(ru)下圖所示:

第二(er)范式(shi)(shi)(The Second Normal Form,2NF):例如訂單詳情表(biao)有這些字(zi)段:訂單 ID、產(chan)(chan)(chan)品 ID、產(chan)(chan)(chan)品名稱、產(chan)(chan)(chan)品單價、折(zhe)扣。其中(zhong),訂單 ID 和(he)產(chan)(chan)(chan)品 ID 為聯合(he)主(zhu)鍵,但這個表(biao)中(zhong)的產(chan)(chan)(chan)品名稱和(he)產(chan)(chan)(chan)品單價兩個字(zi)段只(zhi)依賴產(chan)(chan)(chan)品 ID,和(he)訂單 ID 就沒有任何關系了(le),因此這個表(biao)也(ye)不符(fu)合(he)第二(er)范式(shi)(shi)。
我們可以把(ba)原來的(de)訂(ding)單(dan)(dan)表(biao)拆分為訂(ding)單(dan)(dan)表(biao)和產(chan)(chan)品表(biao),其中訂(ding)單(dan)(dan)表(biao)包含:訂(ding)單(dan)(dan) ID、產(chan)(chan)品 ID、折扣(kou)等(deng)字段(duan);而(er)產(chan)(chan)品表(biao)包含:產(chan)(chan)品 ID、產(chan)(chan)品名(ming)(ming)稱、產(chan)(chan)品單(dan)(dan)價(jia)等(deng)字段(duan)。這樣就消除(chu)了產(chan)(chan)品名(ming)(ming)稱和產(chan)(chan)品單(dan)(dan)價(jia)多次重復出現的(de)情況了,從而(er)避免(mian)了冗余數據的(de)產(chan)(chan)生。

第(di)三范式(shi)(The Third Normal Form,3NF):想要滿足(zu)第(di)三范式(shi)必須先滿足(zu)第(di)二(er)范式(shi),第(di)三范式(shi)要求(qiu)所有(you)的非(fei)主鍵(jian)字(zi)段必須直接依(yi)賴主鍵(jian),且不存在傳遞依(yi)賴的情況。
例(li)如,有一個學(xue)(xue)生表中包含了:學(xue)(xue)生 ID、姓名(ming)、所(suo)(suo)在(zai)學(xue)(xue)院(yuan)(yuan)(yuan) ID、學(xue)(xue)院(yuan)(yuan)(yuan)電話、學(xue)(xue)院(yuan)(yuan)(yuan)地(di)址(zhi)(zhi)等字(zi)(zi)(zi)段(duan)(duan)。這(zhe)個表的所(suo)(suo)有字(zi)(zi)(zi)段(duan)(duan)(除去主(zhu)鍵字(zi)(zi)(zi)段(duan)(duan))都(dou)完全(quan)依(yi)賴(lai)唯一的主(zhu)鍵字(zi)(zi)(zi)段(duan)(duan)(學(xue)(xue)生 ID),所(suo)(suo)以(yi)符合第(di)二范式(shi)。但它存在(zai)一個問(wen)題,學(xue)(xue)院(yuan)(yuan)(yuan)電話、學(xue)(xue)院(yuan)(yuan)(yuan)地(di)址(zhi)(zhi)依(yi)賴(lai)非主(zhu)鍵字(zi)(zi)(zi)段(duan)(duan)學(xue)(xue)院(yuan)(yuan)(yuan) ID,而(er)不是直接依(yi)賴(lai)于主(zhu)鍵,它是通過傳遞才依(yi)賴(lai)于主(zhu)鍵,所(suo)(suo)以(yi)不符合第(di)三范式(shi)。
我們可以(yi)把學(xue)生(sheng)表(biao)(biao)分為(wei)兩(liang)張(zhang)(zhang)表(biao)(biao),一張(zhang)(zhang)是學(xue)生(sheng)表(biao)(biao)包含了:學(xue)生(sheng) ID、姓(xing)名、所在學(xue)院(yuan)(yuan) ID 等字段;另一張(zhang)(zhang)為(wei)學(xue)院(yuan)(yuan)表(biao)(biao)包含了:學(xue)院(yuan)(yuan) ID、學(xue)院(yuan)(yuan)電話、學(xue)院(yuan)(yuan)地址等字段,這樣就滿足第三范(fan)式(shi)的要求(qiu)了。

可(ke)以看出,使用三范式(shi)可(ke)以避免(mian)數據(ju)的(de)冗余,而且在更(geng)新表操作時,只需(xu)要更(geng)新單(dan)張(zhang)表就可(ke)以了。
但隨著互聯網(wang)應用的(de)(de)快(kuai)速發展(zhan),我們(men)需要應對日益復雜且快(kuai)速迭代的(de)(de)數(shu)據(ju)庫,以(yi)應對互聯網(wang)快(kuai)速發展(zhan)的(de)(de)趨勢(shi),于是(shi)誕(dan)生(sheng)了(le)(le)以(yi) MongoDB 為代表的(de)(de)文檔型(xing)數(shu)據(ju)庫。它提供了(le)(le)更(geng)高(gao)效的(de)(de)讀/寫性(xing)能(neng)以(yi)及可自動容災(zai)的(de)(de)數(shu)據(ju)庫集群,還(huan)有靈活的(de)(de)數(shu)據(ju)庫結(jie)構,從(cong)而給系統的(de)(de)數(shu)據(ju)庫存儲帶(dai)來(lai)了(le)(le)更(geng)多可能(neng)性(xing)。
當然 MongoDB 的(de)(de)(de)誕生并不(bu)是(shi)為(wei)了(le)替代關系(xi)(xi)型數(shu)據庫,而是(shi)為(wei)系(xi)(xi)統(tong)的(de)(de)(de)快速開(kai)發(fa)提供一種可能性,它和關系(xi)(xi)型數(shu)據庫是(shi)一種互補的(de)(de)(de)關系(xi)(xi),可供開(kai)發(fa)者在不(bu)同的(de)(de)(de)業務場景下(xia)選(xuan)擇(ze)相(xiang)對(dui)應的(de)(de)(de)數(shu)據庫類型。
非關系型數據庫 VS 文檔型數據庫
非(fei)關系型數(shu)(shu)(shu)據和(he)文檔型數(shu)(shu)(shu)據庫屬(shu)于(yu)包(bao)含(han)關系,非(fei)關系型數(shu)(shu)(shu)據包(bao)含(han)了(le)文檔型數(shu)(shu)(shu)據庫,文檔型數(shu)(shu)(shu)據庫屬(shu)于(yu)非(fei)關系型數(shu)(shu)(shu)據。
非關系型(xing)數據通常包(bao)含 3 種(zhong)數據庫類型(xing):文檔型(xing)數據庫、鍵(jian)值型(xing)數據庫和(he)全文搜(sou)索型(xing)數據庫,下面分別來看每種(zhong)類型(xing)的具體用途。
1. 文檔型數據庫
文(wen)檔型數據(ju)庫(ku)以 MongoDB 和 Apache CouchDB 為(wei)代表,文(wen)檔型數據(ju)庫(ku)通常以 JSON 或者 XML 為(wei)格式進行數據(ju)存儲。
以 MongoDB 為例,它是(shi)由 C++ 編(bian)寫的一種(zhong)面向(xiang)文檔的數(shu)據(ju)庫管理系統,在(zai) 2007 年(nian) 10 月(yue) 由 10gen 團(tuan)隊所開發,并(bing)在(zai) 2009 年(nian) 2 月(yue)首度推出。MongoDB 是(shi)以二(er)進制(zhi) JSON 格式存儲數(shu)據(ju)的,MongoDB 對(dui) JSON 做(zuo)了一些優化,它支(zhi)持了更(geng)多的數(shu)據(ju)類(lei)型(xing),這種(zhong)二(er)進制(zhi)存儲的 JSON 我們(men)也可(ke)以稱之為 BSON(Binary JSON)。
BSON 具(ju)備三個特點:輕(qing)量、可(ke)遍歷以及高效(xiao),它的缺點是空(kong)間(jian)利用(yong)率不是很理想。MongoDB 使用(yong) BSON 進行存(cun)儲的另一個重要原因是 BSON 具(ju)備可(ke)遍歷性。
{"_id":ObjectId(“57ce2d4cce8685a6fd9df3a3"),"name":"老王","email":['java@qq.com','java@163.com']}
其中(zhong),“_id”為(wei) MongoDB 默認的主鍵字段,它會(hui)為(wei)我們(men)生(sheng)成一起全(quan)局(ju)唯(wei)一的 id 值,并且這個值在做數據(ju)分片時非常(chang)有用。
文檔型數據庫(ku)的使用場景如(ru)下(xia)。
敏捷開(kai)發,因(yin)為 MongoDB 擁有(you)比關系型數(shu)據庫(ku)(ku)更快的(de)開(kai)發速(su)度,因(yin)此(ci)很多敏捷開(kai)發組(zu)織,包括紐約時報等都采用(yong)了(le) MongoDB 數(shu)據庫(ku)(ku)。使用(yong)它(ta)可以有(you)效地避免在(zai)增加和(he)修改數(shu)據庫(ku)(ku)帶來(lai)的(de)溝(gou)通成本,以及維護和(he)創(chuang)建(jian)數(shu)據庫(ku)(ku)模(mo)型成本,使用(yong) MongoDB 只需要在(zai)程序(xu)層面嚴格把關就行,程序(xu)提交的(de)數(shu)據結構可以直接更新到(dao)數(shu)據庫(ku)(ku)中,并不需要繁雜的(de)設計數(shu)據庫(ku)(ku)模(mo)型再生成修改語句等過程。
日志(zhi)系統(tong),使用 MongoDB 數據(ju)庫(ku)非常適合存(cun)儲(chu)日志(zhi),日志(zhi)對應到數據(ju)庫(ku)中就是很多個文(wen)(wen)件(jian),而(er) MongoDB 更擅長存(cun)儲(chu)和查(cha)詢(xun)文(wen)(wen)檔,它提供了(le)更簡單的(de)存(cun)儲(chu)和更方便(bian)的(de)查(cha)詢(xun)功能。
社交系統,使用 MongoDB 可以(yi)很方便的(de)存儲(chu)用戶的(de)位(wei)置信息,可以(yi)方便的(de)實現查詢附近(jin)的(de)人以(yi)及附近(jin)的(de)地點等功能。
2. 鍵值型數據庫
鍵值數(shu)據(ju)(ju)(ju)庫(ku)(ku)也就是(shi) Key-Value 數(shu)據(ju)(ju)(ju)庫(ku)(ku),它(ta)的典型代表數(shu)據(ju)(ju)(ju)庫(ku)(ku)是(shi) Redis 和 Memcached,而它(ta)們通(tong)常(chang)被當(dang)做非持(chi)久(jiu)(jiu)化的內存型數(shu)據(ju)(ju)(ju)庫(ku)(ku)緩存來(lai)使(shi)用。當(dang)然 Redis 數(shu)據(ju)(ju)(ju)庫(ku)(ku)是(shi)具備(bei)可持(chi)久(jiu)(jiu)化得能力的,但是(shi)開啟(qi)持(chi)久(jiu)(jiu)化會降低系統(tong)的運行效率(lv),因此在(zai)使(shi)用時(shi)需要根據(ju)(ju)(ju)實際的情況,選擇開啟(qi)或者關閉持(chi)久(jiu)(jiu)化的功(gong)能。
鍵(jian)值型(xing)(xing)(xing)數據(ju)(ju)庫以(yi)極高(gao)的(de)性能著稱(cheng),且除了(le) Key-Value 字(zi)符(fu)串(chuan)類型(xing)(xing)(xing)之外(wai),還包含一些其(qi)他的(de)數據(ju)(ju)類型(xing)(xing)(xing)。以(yi) Redis 為例,它提供了(le)字(zi)符(fu)串(chuan)類型(xing)(xing)(xing)(String)、列表類型(xing)(xing)(xing)(List)、哈希(xi)表類型(xing)(xing)(xing)(Hash)、集合(he)類型(xing)(xing)(xing)(Set)、有(you)(you)序集合(he)類型(xing)(xing)(xing)(ZSet)等五種最(zui)常用的(de)基礎(chu)數據(ju)(ju)類型(xing)(xing)(xing),還有(you)(you)管道類型(xing)(xing)(xing)(Pipeline)、地(di)理(li)位置類型(xing)(xing)(xing)(GEO)、基數統(tong)計類型(xing)(xing)(xing)(HyperLogLog)和(he)流類型(xing)(xing)(xing)(Stream),并(bing)且還提供了(le)消(xiao)息(xi)隊列的(de)功能。
此數(shu)據庫(ku)的優點是(shi)性能(neng)比(bi)較高(gao),缺點是(shi)對事務的支持不是(shi)很好。
3. 全文搜索型數據庫
傳(chuan)統的(de)關(guan)系(xi)型數(shu)據(ju)庫(ku)主要(yao)是(shi)依賴索(suo)(suo)(suo)(suo)引(yin)來實現(xian)(xian)(xian)快速查(cha)(cha)詢(xun)功能的(de),而在全(quan)文搜索(suo)(suo)(suo)(suo)的(de)業務(wu)下,索(suo)(suo)(suo)(suo)引(yin)很(hen)難(nan)滿足查(cha)(cha)詢(xun)的(de)需(xu)求(qiu)。因為全(quan)文搜索(suo)(suo)(suo)(suo)需(xu)要(yao)支持模(mo)糊匹配的(de),當數(shu)據(ju)量比較(jiao)大的(de)情(qing)況下,傳(chuan)遞的(de)關(guan)系(xi)型數(shu)據(ju)庫(ku)的(de)查(cha)(cha)詢(xun)效率是(shi)非(fei)常低的(de);另一個原(yuan)因是(shi)全(quan)文搜索(suo)(suo)(suo)(suo)需(xu)要(yao)支持多條件隨意組合排序,如果(guo)要(yao)通過索(suo)(suo)(suo)(suo)引(yin)來實現(xian)(xian)(xian)的(de)話,則需(xu)要(yao)創建大量的(de)索(suo)(suo)(suo)(suo)引(yin),而傳(chuan)統型數(shu)據(ju)庫(ku)也(ye)很(hen)難(nan)實現(xian)(xian)(xian),因此需(xu)要(yao)專門全(quan)文搜索(suo)(suo)(suo)(suo)引(yin)擎(qing)和相關(guan)的(de)數(shu)據(ju)庫(ku)才能實現(xian)(xian)(xian)此功能。
全(quan)文搜(sou)索型(xing)數據(ju)庫(ku)以(yi) ElasticSearch 和 Solr 為代(dai)表,它們的出現解決(jue)了關系型(xing)數據(ju)庫(ku)全(quan)文搜(sou)索功(gong)能較弱(ruo)的問(wen)題.
MongoDB 事務
MongoDB 在(zai) 4.0 之(zhi)前是(shi)不(bu)支持(chi)事(shi)務的(de),不(bu)支持(chi)的(de)原因(yin)也很簡單,因(yin)為文(wen)檔型數據庫(ku)和(he)傳統的(de)關系型數據庫(ku)不(bu)一樣,不(bu)需(xu)要(yao)滿足(zu)三范式。文(wen)檔型數據庫(ku)之(zhi)所以性能比較高的(de)另一個(ge)主要(yao)原因(yin),就是(shi)使用(yong)文(wen)檔型數據庫(ku)不(bu)用(yong)進行多(duo)表(biao)關聯(lian)性查(cha)(cha)詢(xun),因(yin)為文(wen)檔型數據庫(ku)會把(ba)相(xiang)關的(de)信息(xi)存放到一張表(biao)中。因(yin)此(ci),無(wu)需(xu)關聯(lian)多(duo)表(biao)查(cha)(cha)詢(xun)的(de) MongoDB,在(zai)這種(zhong)情(qing)況下的(de)查(cha)(cha)詢(xun)性能是(shi)比較高的(de)。
把所有相關的(de)數據都放入(ru)一個表中,這也是 MongoDB 之前很長(chang)一段時間內不(bu)支持事務的(de)原因,它可(ke)以保證(zheng)單表操作的(de)原子性(xing),一條(tiao)記錄(lu)要么成(cheng)功(gong)插入(ru),要么插入(ru)失敗(bai),不(bu)會存(cun)在插入(ru)了(le)一半的(de)數據。因此(ci),在這種設計思路下,MongoDB 官方認(ren)為“事務功(gong)能”的(de)實(shi)現沒有那(nei)么緊迫(po)。
但(dan)在(zai) MongoDB 4.0 之中(zhong)正式添加(jia)了事(shi)務的(de)功(gong)能,并且在(zai) MongoDB 4.2 中(zhong)實現了分布式事(shi)務的(de)功(gong)能,至此(ci) MongoDB 開啟(qi)了支持事(shi)務之旅。
————————————————
版權聲明:本文為(wei)CSDN博(bo)主「HCH996」的原(yuan)創(chuang)文章(zhang),遵循CC 4.0 BY-SA版權協議(yi),轉載請附上(shang)原(yuan)文出處鏈接及本聲明。
原文(wen)鏈接://blog.csdn.net/weixin_37841366/article/details/108900754
