簡單說來:sql是關(guān)系型數(shù)據(jù)庫的結(jié)構(gòu)化查詢語言,而nosql,一般代指菲關(guān)系型數(shù)據(jù)庫,sql語句就不能用來,不過有些有l(wèi)eisql的查詢語言,且nosql數(shù)據(jù)庫沒有統(tǒng)一的查詢語言。
10年積累的成都網(wǎng)站制作、網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先建設(shè)網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有愛輝免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
一樣是數(shù)據(jù)庫
NOSQL查詢速度快,但是占用空間也大(都去索引那邊了)
但是NOSQL查詢復(fù)雜的邏輯關(guān)系的時(shí)候,只能批量獲取到本地去統(tǒng)計(jì)而SQL能通過條件和關(guān)聯(lián)表等方式進(jìn)行篩選只顯示符合條件的語句。
NOSQL用于無條件或少條件下的存取。百億級(jí)數(shù)據(jù)也能快速取出。
SQL用于復(fù)雜的邏輯存取。在數(shù)據(jù)量不多的情況下也能跟NOSQL一樣用于數(shù)據(jù)存儲(chǔ)。
如何選擇數(shù)據(jù)庫
柳樹
公眾號(hào):柳樹的絮叨叨
關(guān)注他
30 人贊同了該文章
我們正在做一個(gè)電子書小程序。
1.0 層次模型數(shù)據(jù)庫
用戶購買,生成訂單,訂單詳情里有用戶購買的電子書:
一層一層鋪開,一對(duì)多,這是「層次模型數(shù)據(jù)庫」(Hierarchical Database)。
2.0 網(wǎng)狀模型數(shù)據(jù)庫
一筆訂單可以購買多本電子書,一本電子書也可以被多筆訂單購買:
這就形成了「多對(duì)多」的「網(wǎng)狀模型數(shù)據(jù)庫」(Network Database)。
上面講的兩種數(shù)據(jù)庫,也許你聽都沒聽過。
我們用的,是「關(guān)系模型」,而非上面的「層次模型」或者「網(wǎng)狀模型」。
為什么?
你會(huì)說,這樣不方便遍歷所有訂單。
并不會(huì),再加一個(gè)根節(jié)點(diǎn)就好:
你會(huì)說,這樣查找效率很低。
也不會(huì),因?yàn)榭梢詢?yōu)化下數(shù)據(jù)結(jié)構(gòu),比如換成 B+ 樹。
為什么我們從一開始就在用「關(guān)系模型數(shù)據(jù)庫」?
3.0 關(guān)系模型數(shù)據(jù)庫
無論是層次模型還是網(wǎng)狀模型,程序員看到的,都是實(shí)實(shí)在在的物理存儲(chǔ)結(jié)構(gòu)。
查詢時(shí),你要照著里面的數(shù)據(jù)結(jié)構(gòu),用對(duì)應(yīng)的算法來查;
插入時(shí),你也要照著數(shù)據(jù)結(jié)構(gòu),用對(duì)應(yīng)算法來插入,否則你就破壞了數(shù)據(jù)的組織結(jié)構(gòu),數(shù)據(jù)也就壞掉了。
因?yàn)槲覀兌紱]用過前面兩種數(shù)據(jù)庫,所以覺得「關(guān)系模型數(shù)據(jù)庫」(以下簡稱 RDB)的一切都理所當(dāng)然,但其實(shí),它做出了一個(gè)革命性的變革:
用邏輯結(jié)構(gòu)(logical representation of data)代替物理結(jié)構(gòu)(physical representation of data)
所謂「邏輯結(jié)構(gòu)」,也就是我們經(jīng)??吹降摹副砀瘛梗琔ser 是一張表格,Order 是一張表格,Book 又是一張表格,它們之間的關(guān)系,用 id 來關(guān)聯(lián),這些 id,可能是 number 類型,也可能是 string 類型
但你看到的,不一定就是實(shí)際的,你看到的只是讓你方便理解的「邏輯結(jié)構(gòu)」,真實(shí)數(shù)據(jù)自然不是這樣按表格來存儲(chǔ),表格無異于一個(gè)數(shù)組,數(shù)組查詢是很慢的。
真實(shí)的「物理結(jié)構(gòu)」,也許還是像「層次模型」和「網(wǎng)狀模型」一樣,是復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
但到底是怎樣的數(shù)據(jù)結(jié)構(gòu),你都無需關(guān)心,你只需把它想象成一張「表」去操作,就連可視化工具,都會(huì)幫你把數(shù)據(jù)可視化成表,來方便你理解。
這個(gè)觀念的提出,來自于 1970 年 Codd 的一篇論文,A Relational Model of Data for Large Shared Data Banks:
Future users of large data banks must?be protected from having to know how the data is organized in the machine?(the internal representation).?
Activities of users at terminals and most application programs should?remain unaffected when the internal representation of data is changed?and even when some aspects of the external representation are changed.?
—— Codd
Codd 的這種思想,其實(shí)就是經(jīng)濟(jì)學(xué)里提到的:分工產(chǎn)生效能。
程序員們不需要直接和物理結(jié)構(gòu)打交道,只負(fù)責(zé)告訴數(shù)據(jù)庫,他想做什么,至于數(shù)據(jù)是如何存儲(chǔ)、如何索引,都交給數(shù)據(jù)庫,最終他們看到的就是一張張?zhí)貏e直觀、特別好理解的 excel 表格。
而數(shù)據(jù)庫則把維護(hù)物理結(jié)構(gòu)的復(fù)雜邏輯,交給了自己, 對(duì)程序員屏蔽了復(fù)雜的實(shí)現(xiàn)細(xì)節(jié)。
開發(fā)時(shí)寫的代碼少了,耦合性降低了,數(shù)據(jù)也不容易損壞,也就提高了生產(chǎn)效率(productive)。
一切能用同樣的耗能,帶來更多效能的技術(shù),都會(huì)被廣泛使用。
NoSQL
那后來為什么又有了 NoSQL 呢?
在 RDB 被發(fā)明的時(shí)代,軟件多用于大型企業(yè),比如銀行、金融等等,人們對(duì)數(shù)據(jù)的要求非常純粹:準(zhǔn)確、可靠、安全,讓數(shù)據(jù)按照期望,正確的寫入,不要給老子算錯(cuò)錢就好,于是有了具有 ACID 特性的事務(wù):原子性、一致性、隔離性和持久性。
那時(shí)候用網(wǎng)絡(luò)的人很少,通過終端來訪問客戶端的人,更少,自然的,數(shù)據(jù)庫的數(shù)據(jù)量和訪問量都跟現(xiàn)在沒法比,一臺(tái)機(jī)器,足矣,最多再來個(gè)一主多從:
后來,你知道的,每個(gè)人手里都有個(gè)手機(jī),每分每秒,都有成千上萬的數(shù)據(jù),寫入你的數(shù)據(jù)庫、從你的數(shù)據(jù)庫被查出,于是有了「分布式」,有了 BASE 和 CAP。這時(shí)候,RDB 就會(huì)發(fā)現(xiàn),自己之前的那一套 ACID,竟然有點(diǎn)作繭自縛了:
為了保證事務(wù)的隔離性,要進(jìn)行加鎖,在分布式的環(huán)境下,就要對(duì)多臺(tái)機(jī)器的數(shù)據(jù)進(jìn)行加鎖;
為了保證事務(wù)的原子性,在機(jī)器 A 的操作和在機(jī)器 B 的操作,要么一起成功,要么一起失?。?/p>
…...
這些都要去不同節(jié)點(diǎn)的機(jī)器進(jìn)行通訊和協(xié)調(diào),實(shí)現(xiàn)起來非常復(fù)雜,而且要付出更多的網(wǎng)絡(luò) IO,影響性能。
ACID 在分布式系統(tǒng)上實(shí)現(xiàn)起來就會(huì)變得難以實(shí)現(xiàn),即使實(shí)現(xiàn)了,也要付出很大的性能成本,于是才有了后來的各種「分布式一致性協(xié)議」,Paxos、Raft、2PC …… 而 Mysql 也提供了各種方案來實(shí)現(xiàn)分布式,當(dāng)然,這些方案自然是很復(fù)雜的,比如 「NDB Cluster」 :
而 NoSQL 則沒有這么多承諾,它的一致性,一般都是最終一致性,當(dāng)然你可以選擇強(qiáng)一致,那自然就要付出點(diǎn)性能作為代價(jià),當(dāng)然你還可以弱一致,這樣會(huì)更不安全,但是更快,一切取決于你對(duì)數(shù)據(jù)的要求。
除此之外,RDB 的「數(shù)據(jù)庫范式」(Database Schema),也成了限制擴(kuò)展性的瓶頸。為了避免數(shù)據(jù)冗余導(dǎo)致的各種問題(占用空間、刪除異常、更新異常等等),我們?cè)谠O(shè)計(jì)關(guān)系模型時(shí),通常都是按照最小單位來設(shè)計(jì)的。
什么叫最小單位,比如用戶有地址和愛好,那么在正確設(shè)計(jì)的關(guān)系模型(比如 3NF)里,這就是三張表:
如果這三張表被分散在不同的機(jī)器,那進(jìn)行關(guān)聯(lián)查詢時(shí),就需要多次跨機(jī)器的通訊;
而對(duì)于 NoSQL,這三類信息,都可以利用 Json 格式的數(shù)據(jù),將它們存放在一起:
完整的存儲(chǔ)進(jìn)去,完整的取出來,不需要額外的操作。
NoSQL 比 RDB 有更強(qiáng)的擴(kuò)展性,可以充分利用分布式系統(tǒng)來提升讀寫性能和可靠性。
這不是誰設(shè)計(jì)好壞的問題,而是跟他們要解決的問題有關(guān):RDB 誕生于互聯(lián)網(wǎng)萌芽的時(shí)代,那時(shí)數(shù)據(jù)的準(zhǔn)確、可靠是最重要的,而 NoSQL 誕生于互聯(lián)網(wǎng)快速發(fā)展普及的時(shí)代,大數(shù)據(jù)、分布式、擴(kuò)展性成了數(shù)據(jù)庫的另一個(gè)重要特性。
總結(jié)一下:
RDB 首先得是準(zhǔn)確、可靠,然后才向更高的「可拓展性」發(fā)展;
而 NoSQL 生而分布式,可拓展性強(qiáng),然后才向更高的「準(zhǔn)確性」發(fā)展。
NoSQL ,not only SQL,其實(shí)就是對(duì)那種打破了 RDB 嚴(yán)格事務(wù)和關(guān)系模型約束的那些數(shù)據(jù)庫的泛指,而隨著要解決的問題的不同,又誕生了各種各樣的 NoSQL。
首先是「列式數(shù)據(jù)庫」(Column-oriented DBMS),數(shù)據(jù)量上去了,我們想分析網(wǎng)站用戶的年齡分布,簡單說,就是你需要對(duì)同一個(gè)特征進(jìn)行大數(shù)據(jù)量的分析統(tǒng)計(jì),于是把原來 RDB 的「按行存儲(chǔ)」的范式打破,變成了「按列存儲(chǔ)」,比如 HBase;
然后你發(fā)現(xiàn)有些數(shù)據(jù)變動(dòng)不是很大,但是經(jīng)常需要被查詢, 查詢時(shí)還要關(guān)聯(lián)很多張表,于是你把這些來自不同表的數(shù)據(jù),揉成一個(gè)大對(duì)象,按 key-value 的格式存起來,比如 Redis;
再后來你需要對(duì)博客內(nèi)容進(jìn)行相關(guān)性搜索,傳統(tǒng) RDB 不支持相關(guān)性搜索,最重要的,還是擴(kuò)展性差,增加機(jī)器的帶來邊際效益有限,于是有了「全文搜索引擎」,比如 Elasticsearch;
除此之外,還有「文檔數(shù)據(jù)庫」、「圖形數(shù)據(jù)庫」……
沒有一種數(shù)據(jù)庫是銀彈。
總結(jié)
這篇文章的題目是「如何選擇數(shù)據(jù)庫」,這是困擾很多人的問題,那么多數(shù)據(jù)庫,到底要選什么好?
可是當(dāng)你問出這樣一個(gè)問題時(shí),其實(shí)你是在問一種「手段」。我現(xiàn)在要做這樣一個(gè)需求,用什么數(shù)據(jù)庫可以幫我實(shí)現(xiàn)它?
但其實(shí)你需要的不只是一種「手段」,因?yàn)槿绻麑?duì)方甩給你一個(gè)冷冰冰的名字,Mysql、Elasticsearch、MongoDB,你肯定會(huì)問,憑什么?
你需要的,是一種「解決方案」。如果你需要數(shù)據(jù)十分嚴(yán)格準(zhǔn)確,分毫不差,那我會(huì)推薦你采用「事務(wù)」和「關(guān)系模型」來處理數(shù)據(jù);如果你需要數(shù)據(jù)能夠被大量讀取和寫入,那我會(huì)推薦你擴(kuò)展性強(qiáng)的「分布式」;如果你的數(shù)據(jù)經(jīng)常是整個(gè)讀取、整個(gè)更新的,那「關(guān)系模型」就沒有「文檔模型」適合你。
「事務(wù)」、「關(guān)系模型」、「分布式」、「文檔模型」等等,這些就是「解決方案」,知道用什么「解決方案」,用哪個(gè)數(shù)據(jù)庫,自然水到渠成。
正如一位大牛說的:
設(shè)計(jì)實(shí)踐中,要基于需求、業(yè)務(wù)驅(qū)動(dòng)架構(gòu)。無論選用 RDB/NoSQL,一定是以需求為導(dǎo)向,最終數(shù)據(jù)存儲(chǔ)方案必然是各種權(quán)衡的綜合性設(shè)計(jì)。
用戶不會(huì)因?yàn)槟阌昧?Mysql 或者 MongoDB 而使用你的軟件,畢竟絕大多數(shù)用戶都不知道 Mysql 和 MongoDB 是什么玩意。
NoSQL與關(guān)系型數(shù)據(jù)庫設(shè)計(jì)理念比較
關(guān)系型數(shù)據(jù)庫中的表都是存儲(chǔ)一些格式化的數(shù)據(jù)結(jié)構(gòu),每個(gè)元組字段的組成都一樣,即使不是每個(gè)元組都需要所有的字段,但數(shù)據(jù)庫會(huì)為每個(gè)元組分配所有的字段,這樣的結(jié)構(gòu)可以便于表與表之間進(jìn)行連接等操作,但從另一個(gè)角度來說它也是關(guān)系型數(shù)據(jù)庫性能瓶頸的一個(gè)因素。而非關(guān)系型數(shù)據(jù)庫以鍵值對(duì)存儲(chǔ),它的結(jié)構(gòu)不固定,每一個(gè)元組可以有不一樣的字段,每個(gè)元組可以根據(jù)需要增加一些自己的鍵值對(duì),這樣就不會(huì)局限于固定的結(jié)構(gòu),可以減少一些時(shí)間和空間的開銷。
特點(diǎn):
它們可以處理超大量的數(shù)據(jù)。
它們運(yùn)行在便宜的PC服務(wù)器集群上。
它們擊碎了性能瓶頸。
沒有過多的操作。
Bootstrap支持
缺點(diǎn):
但是一些人承認(rèn),沒有正式的官方支持,萬一出了差錯(cuò)會(huì)是可怕的,至少很多管理人員是這樣看。
此外,nosql并未形成一定標(biāo)準(zhǔn),各種產(chǎn)品層出不窮,內(nèi)部混亂,各種項(xiàng)目還需時(shí)間來檢驗(yàn)