自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL它不香嗎,為什么還要NoSQL?

數(shù)據(jù)庫 MySQL
NoSQL 現(xiàn)在非常火,我看過的簡歷里面十個有九個都寫了熟悉 NoSQL,但是對于 NoSQL 背后的細(xì)節(jié)卻很少有人能講清楚,甚至連 NoSQL 里面的這個 No 是什么意思都很多人搞錯。

NoSQL 現(xiàn)在非?;穑铱催^的簡歷里面十個有九個都寫了熟悉 NoSQL,但是對于 NoSQL 背后的細(xì)節(jié)卻很少有人能講清楚,甚至連 NoSQL 里面的這個 No 是什么意思都很多人搞錯。

[[324265]]

圖片來自 Pexels

這個 No 并不是 Not 的意思,而是 Not Only 的縮寫。不得不說這個縮寫實(shí)在是很坑爹,單從字面上應(yīng)該沒人能猜出來它是這個意思。

而且即使解讀成 Not Only SQL,還是有點(diǎn)云里霧里,不是很能精準(zhǔn)地 get 到它的點(diǎn)。

因?yàn)?SQL 的英文全寫是 Structured Query Language,也就是結(jié)構(gòu)化查詢語言的意思。它可以認(rèn)為是一門特殊的編程語言,但“不僅僅是 SQL”是啥意思?

的確令人費(fèi)解,所以我們從字面意思上去理解是不行的,我們需要從實(shí)際應(yīng)用場景去理解。

SQL 的應(yīng)用場景是關(guān)系型數(shù)據(jù)庫,比如我們常用的 Oracle、MySQL,這些就是關(guān)系型數(shù)據(jù)庫。

我們理解數(shù)據(jù)庫的時(shí)候,往往會從表的結(jié)構(gòu)入手去理解。數(shù)據(jù)庫當(dāng)中存儲的是一張張的表,表呢是一行行數(shù)據(jù)組成的,而每一行數(shù)據(jù)都有固定的字段。

我想這點(diǎn)大家應(yīng)該非常熟悉,即使沒有學(xué)過數(shù)據(jù)庫或者是像我這樣已經(jīng)還給老師的,應(yīng)該或多或少都有印象。

但是為什么它會被叫做關(guān)系型數(shù)據(jù)庫,而不是表結(jié)構(gòu)數(shù)據(jù)庫呢?

因?yàn)樵跀?shù)據(jù)庫當(dāng)中,關(guān)系要比表結(jié)構(gòu)更重要。表結(jié)構(gòu)只是一種形式,而數(shù)據(jù)庫當(dāng)中核心的設(shè)計(jì)理念其實(shí)是關(guān)系。

這也是為什么我們學(xué)習(xí)數(shù)據(jù)庫的時(shí)候都需要從 ER 圖開始,而不是上來就講數(shù)據(jù)庫使用的方法,或者是 SQL 語言的細(xì)節(jié)。

如果你想不明白這句話的含義,也沒有關(guān)系,我們先放一放,最后再回到這個話題來。

問題來了,我們知道了常用的 SQL 數(shù)據(jù)庫是關(guān)系型數(shù)據(jù)庫,那么 NoSQL 代表的數(shù)據(jù)庫又是什么呢?

關(guān)于 NoSQL 概念我至少看到了兩種說法:

  • 非關(guān)系型數(shù)據(jù)庫
  • 文檔型數(shù)據(jù)庫

我個人在理解的時(shí)候覺得這兩種說法都不是非常完美,但相比之下顯然是第二種更好,因?yàn)榈谝环N說法完全沒有給我們提供任何信息。

文檔型數(shù)據(jù)庫這里的文檔,并不是我們常規(guī)理解的一篇文檔的含義,而是指的數(shù)據(jù)存儲的結(jié)構(gòu)和核心邏輯。

一個生動的例子

和大多數(shù)技術(shù)上的概念一樣,NoSQL 也比較晦澀,很難單純用語言將它描述清楚。

所以我決定舉一個生動活潑,大家都耳熟能詳?shù)睦?mdash;—就是萬能的 X 寶。

下面是一張 X 寶當(dāng)中的商品詳情頁的圖(隨便選取,并非廣告,如有巧合,請付推廣費(fèi)):

這張圖大家應(yīng)該都很熟悉了,在我們平時(shí)的網(wǎng)上購物的活動當(dāng)中,一定見過了許多次。

它看起來有些眼花繚亂,我們把上面的內(nèi)容做個抽象和精簡,畫成一張草圖,它大概是這樣的(的確有些草率):

也就是說我們把一個商品詳情頁展示的內(nèi)容大概分成了三個部分:

  • 商品圖
  • 商品的一些介紹說明
  • 用戶的評論

各大電商公司商品詳情頁的設(shè)計(jì)大同小異,也許有些細(xì)節(jié)不太一樣,但是整體上的模塊都相差不大。

為了簡化問題,我們就假設(shè)商品詳情頁需要關(guān)聯(lián)圖片信息、文字說明和用戶評論這三張表。

其實(shí)這樣劃分不太科學(xué),比如文字介紹和商品圖可以都存在商品詳情頁的表中。

比如除了這些信息之外,還有商品的售賣信息,比如庫存、價(jià)格、當(dāng)前的優(yōu)惠、活動等等,但是這些和我們最后的結(jié)論關(guān)系不大,可以簡單這么理解。

根據(jù)上面的劃分方式,我們應(yīng)該根據(jù) itemID 去查詢商品的圖片、文字以及評論信息,這從表面上看當(dāng)然沒有問題。

但實(shí)際上這是有問題的,問題在于這些數(shù)據(jù)都不是一對一的關(guān)系,而是一對多的關(guān)系。

比如頭部展示的圖片往往不止一張,文字說明可能也不止一段,同樣用戶的評論可能也不止一條。這個問題怎么解決呢?

你可能會想出辦法來,這不難啊,我們在 img 和 text 以及 comment 的表里都加入 itemID 這個字段,在我們查詢的時(shí)候通過 itemID 進(jìn)行關(guān)聯(lián),不就 OK 了么?

這樣做當(dāng)然可以,假設(shè)你是負(fù)責(zé)這個項(xiàng)目的程序員,你做出了這個更新,成功上線了之后,產(chǎn)品又給你提了一個新的需求。

她說我想要在文字介紹和用戶評論里面都展示圖片,雖然系統(tǒng)一開始不是這么設(shè)計(jì)的,但是我不管,我就是需要,立刻馬上。

你翻了好一會白眼,冷靜了許久,想了想,終于想到了兩種方案:

  • 第一個方案是在目前的圖片表上加上字段,用來判斷圖片的用途是詳情頁展示還是評論頁展示,把之后要加的文本介紹和評論頁中的圖片依然存在這張表上。
  • 第二個方案是重新建新的表,專表專用,專門負(fù)責(zé)存放評論頁和說明頁的圖片。

第一個方案的好處是我們不用建新的表,避免了表的冗余,如果每一個需求都需要建新的表,顯然對于后續(xù)的維護(hù)是一個巨大的負(fù)擔(dān)。

但是它的缺點(diǎn)是我們需要批量修正之前所有的數(shù)據(jù),因?yàn)橹暗臄?shù)據(jù)里沒有來源這個字段。

當(dāng)然你也可以不加這個字段,直接用 ID 區(qū)分,但是這是不符合規(guī)范的,而且必然會留下安全隱患。

第二個方案的優(yōu)點(diǎn)是操作簡單,不需要變更之前的數(shù)據(jù),安全風(fēng)險(xiǎn)較小,但問題是需要占用新的資源,利用率低。

因?yàn)橛行┰斍轫摰膱D片和頂部的圖片是可以共用的,這樣分開存儲的話就需要存儲多份。

這兩個方案各有優(yōu)缺點(diǎn),似乎都還不錯,但坑爹的是它們都有一個共同的缺點(diǎn),就是都會增加目前系統(tǒng)和查詢的復(fù)雜度。

一個是要增加查詢時(shí)候傳入的字段,一個是要發(fā)起額外的查詢,不論選擇哪一個,都會讓系統(tǒng)越來越復(fù)雜。

到了后來,一個用戶請求傳來,會帶動數(shù)十個聯(lián)動請求,才能拼裝出完整的數(shù)據(jù)。

現(xiàn)在最新版本的 X 寶的詳情頁商品介紹的部分一律用圖片展示,沒有了文字,也許背后就是受到這個問題的驅(qū)動。

我們回顧一下這個例子,為什么我們的查詢會很復(fù)雜,其實(shí)就和數(shù)據(jù)庫的核心理念有關(guān)。

關(guān)系型數(shù)據(jù)庫存儲的數(shù)據(jù)是關(guān)系,在這個問題當(dāng)中,我們一個詳情頁的查詢,需要查詢商品和圖片的關(guān)系,商品和說明的關(guān)系,商品和評論的關(guān)系,評論和圖片的關(guān)系等等。

也就是說我們最終看到的頁面,其實(shí)是這一系列關(guān)系擰在一起的結(jié)果,每一次查詢的背后都是一個關(guān)系分解再合并的過程,因此會非常復(fù)雜。

文檔型數(shù)據(jù)庫

我們剛才看了關(guān)系型數(shù)據(jù)庫在電商場景下的問題,我們再來看下文檔型數(shù)據(jù)庫在同樣場景下的表現(xiàn)。

和關(guān)系型數(shù)據(jù)庫不同,文檔型數(shù)據(jù)庫存儲的核心是文檔。當(dāng)然這里的文檔指的不是我們通常意義上的文檔,而是 Json 或者是 XML 格式的數(shù)據(jù)。在目前的 NoSQL 數(shù)據(jù)庫當(dāng)中,Json 類型的數(shù)據(jù)更加常用一些。

我們還用剛才詳情頁的例子來看下在 NoSQL 數(shù)據(jù)庫當(dāng)中,這份數(shù)據(jù)是如何存儲的:

  1.   "itemID": 123, 
  2.   "itemName""iPad Pro"
  3.   "topImgs": ["imgs1.path""imgs2.path"], 
  4.   "desc": [{"text""iPad Pro""img"""}, {"text""2020 new version""img""imgs1.path"}], 
  5.   "comments": [{"userName""chengzhi""comment""good product""imgs": ["imgs3.path""img4.path"]}] 

你看,在文檔型數(shù)據(jù)庫當(dāng)中剛才復(fù)雜的、需要經(jīng)過多次查詢經(jīng)過一系列處理才可以擰到一起的數(shù)據(jù),我們通過 itemID 一次查詢就可以獲取到了。

單純從使用上來說,它比關(guān)系型數(shù)據(jù)庫要方便了許多,但是它也并不是沒有缺點(diǎn)的。

這其中一個很大的問題是,我們把所有數(shù)據(jù)都直接存儲在了文檔當(dāng)中,這一方面造成了數(shù)據(jù)的冗余,另一方面也限制了拓展性。

比如說,同一個商家下類似的商品不能共享圖片,而必須存儲多份,這造成了空間的浪費(fèi)。

再比如,假設(shè)我們希望支持用戶修改之前過去的評論會非常麻煩,因?yàn)槲覀儽仨氁业剿写鎯α擞脩粼u論的文檔進(jìn)行修改(假設(shè)在其他場景下也用到了用戶評論),這往往是跨系統(tǒng)并且非常不方便的。

這個問題也并不是不可解的,比如我們可以把文檔當(dāng)中存儲的具體數(shù)據(jù)換成一個 ID。

比如 Comment 當(dāng)中不再存儲具體的圖片和評論信息,而存儲一個評論的 ID,在使用的時(shí)候再去關(guān)聯(lián)。

由于文檔型數(shù)據(jù)庫由于架構(gòu)的原因,對于關(guān)聯(lián)的支持并不好,往往需要我們手動根據(jù) ID 再去查詢來模擬連接,這也會帶來額外的開銷。

另外一個小瑕疵是在文檔型數(shù)據(jù)庫當(dāng)中我們訪問數(shù)據(jù)的路徑變長了,舉個例子,加入我們要獲取商品評論當(dāng)中的第二條中的第一張圖片。

我們需要寫成 item['comments'][1]['imgs'][0],而在關(guān)系型數(shù)據(jù)庫當(dāng)中,由于圖片是通過關(guān)系直接查詢得到的,因此要方便一些。

除了這些之外,NoSQL 數(shù)據(jù)庫發(fā)展的年限和 MySQL 這些較成熟的關(guān)系型數(shù)據(jù)庫相比要短得多,因此支持的特性相對比較少。

總結(jié)

通過一個例子,我們很生動地對比了關(guān)系型數(shù)據(jù)庫和 NoSQL 數(shù)據(jù)庫之間的差別。

為什么我們在學(xué)習(xí)數(shù)據(jù)庫的時(shí)候需要先從 ER 圖開始,而不是直接學(xué)習(xí)數(shù)據(jù)庫的原理和它的使用方法呢?我想理解了上面的例子之后,再來看這個問題應(yīng)該會簡單許多。

因?yàn)殛P(guān)系型數(shù)據(jù)庫的核心邏輯就是存儲關(guān)系,使用規(guī)范、各種技巧和特性,本質(zhì)上都是圍繞這個核心展開的。

如果我們沒有 Get 到這一層就來使用數(shù)據(jù)庫很容易走偏,很多匪夷所思的操作就是這么來的。

比如有人在數(shù)據(jù)庫當(dāng)中存儲前端頁面的代碼,比如把 ID 拼接成一個字符串來實(shí)現(xiàn)存儲多個值等等。

這也說明了經(jīng)典教材上的內(nèi)容沒有廢話,每一個章節(jié)都有它預(yù)期的作用,因此當(dāng)我們覺得某些內(nèi)容沒有用的時(shí)候,可能并不是教材錯了,只是我們沒有理解到位。

作者:梁唐

編輯:陶家龍

出處:轉(zhuǎn)載自微信公眾號 TechFlow(ID:techflow2019)

 

責(zé)任編輯:武曉燕 來源: TechFlow
相關(guān)推薦

2021-05-19 09:37:45

SessionTokencookie

2021-04-06 10:48:52

MySQLElasticsear數(shù)據(jù)庫

2020-12-29 05:29:39

DockerK8s容器

2020-10-23 15:18:39

戴爾

2021-07-08 06:52:41

ESClickHouse Lucene

2020-12-25 09:07:38

EclipseCode工具

2017-05-15 16:30:49

NoSQLMySQLOracle

2020-07-30 09:10:21

DockerK8s容器

2020-09-27 08:12:09

Nginx反向代理負(fù)載均衡

2023-01-12 09:01:01

MongoDBMySQL

2015-04-16 15:42:21

關(guān)系型數(shù)據(jù)庫NoSQL

2019-12-18 09:42:19

技術(shù) Linux網(wǎng)絡(luò)

2025-04-14 01:11:00

2021-03-02 22:10:10

Java互聯(lián)網(wǎng)語言

2021-04-16 23:28:11

Java語言IT

2022-06-07 08:39:35

RPCHTTP

2019-01-18 12:50:57

NoSQL數(shù)據(jù)庫Oracle

2020-03-23 07:15:35

物聯(lián)網(wǎng)IOT物聯(lián)網(wǎng)技術(shù)

2019-08-05 14:23:43

DockerKubernetes容器

2024-07-11 10:41:07

HTTPSHTTP文本傳輸協(xié)議
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號