<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:有了SQL,為什么還要用 NoSQL?

          共 4870字,需瀏覽 10分鐘

           ·

          2021-03-26 08:35

          點(diǎn)擊關(guān)注上方“SQL數(shù)據(jù)庫(kù)開(kāi)發(fā)”,

          設(shè)為“置頂或星標(biāo)”,第一時(shí)間送達(dá)干貨

          SQL專(zhuān)欄

          SQL基礎(chǔ)知識(shí)第二版
          SQL高級(jí)知識(shí)第二版

          本文來(lái)自我的一次真實(shí)面試經(jīng)歷。

          這家公司的真名就叫做“三藏”,和我的名字“悟空”很契合,唐三藏給悟空面試,合情合理,還帶有一絲趣味,所以我就去面試了。三藏公司是一家小廠,技術(shù)負(fù)責(zé)人面的我,欲知面試結(jié)果,文末揭曉。

          本文主要內(nèi)容如下:

          一、MongoDB 和 MySQL

          1.面試官:看你的簡(jiǎn)歷上寫(xiě)了 MongoDB,說(shuō)下 MongoDB 和 MySQL 的區(qū)別吧。

          其實(shí)對(duì)于這個(gè)問(wèn)題,我事先有準(zhǔn)備,簡(jiǎn)歷上寫(xiě)了 MongoDB,面試官肯定會(huì)問(wèn) MongoDB 和 MySQL 的區(qū)別。

          MongoDB 是非關(guān)系型的數(shù)據(jù)庫(kù)(NoSQL),屬于文檔型數(shù)據(jù)庫(kù),文檔數(shù)據(jù)庫(kù)就是為了解決關(guān)系數(shù)據(jù)庫(kù)帶來(lái)的問(wèn)題。最大的特點(diǎn)是 no-schema,可以存儲(chǔ)和讀取任意的數(shù)據(jù)。

          存儲(chǔ)的數(shù)據(jù)格式就是 JSON(或者 BSON)。JSON 格式我們都比較熟悉,比如 Rest API 請(qǐng)求返回的 Response 就是 JSON 格式的。JSON 格式的數(shù)據(jù)和 XML 格式的區(qū)別是 JSON 更簡(jiǎn)單,沒(méi)有那么多的標(biāo)簽來(lái)定義字段名。也就是說(shuō) JSON 是自描述的。另外 JSON 格式存進(jìn) MongoDB 中后,即使讀取一個(gè) JSON 中不存在的字段也不會(huì)導(dǎo)致 SQL 那樣的語(yǔ)法錯(cuò)誤。

          MongoDB 優(yōu)點(diǎn)

          由于文檔數(shù)據(jù)庫(kù)具有 no-schema 特性,用起來(lái)有以下幾個(gè)明顯的好處。

          (1)新增的字段不會(huì)出錯(cuò)。

          比如用戶表增加一個(gè)昵稱(chēng)的字段,不需要像關(guān)系型數(shù)據(jù)那樣執(zhí)行更新表結(jié)構(gòu)的語(yǔ)句。我們直接查詢這條文檔出來(lái)就可以看到新增的字段了。

          (2)查詢歷史數(shù)據(jù)不會(huì)出錯(cuò)。

          上面提到新增了一個(gè)昵稱(chēng)字段,但是歷史數(shù)據(jù)中是沒(méi)有這個(gè)字段,如果查詢歷史數(shù)據(jù),則返回的數(shù)據(jù)中不會(huì)有這個(gè)字段,雖然查詢不會(huì)報(bào)錯(cuò),但是取值時(shí),會(huì)返回 null。如果業(yè)務(wù)代碼中用到了昵稱(chēng)字段,則需要做兼容性處理。

          (3)輕松存儲(chǔ)復(fù)雜數(shù)據(jù)。

          因?yàn)槭怯?JSON 存儲(chǔ),而 JSON 又可以表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu),比如字段可以存數(shù)組,字段可以嵌套字段,而且可以存很多字段。換做 MySQL,則需要設(shè)計(jì)幾張表來(lái)存。MongoDB 存數(shù)據(jù)的結(jié)構(gòu),特別適合電商這種業(yè)務(wù)場(chǎng)景,比如兩種不同的商品,屬性差別就很大,但是用 JSON 存就可以輕松應(yīng)對(duì)。

          但是文檔數(shù)據(jù)庫(kù)有什么缺點(diǎn)呢 ?

          MongoDB 缺點(diǎn)

          (1)目前 4.0 以前不支持多文檔事務(wù)。

          結(jié)合 MongoDB 文檔模型內(nèi)嵌數(shù)組、文檔的支持,目前的單文檔事務(wù)能滿足絕大部分開(kāi)發(fā)者的需求。為了讓 MongoDB 能適應(yīng)更多的應(yīng)用場(chǎng)景,讓開(kāi)發(fā)變得更簡(jiǎn)單,MongoDB 4.0 將支持復(fù)制集內(nèi)部跨一或多個(gè)集合的多文檔事務(wù),保證針對(duì)多個(gè)文檔的更新的原子性。而在未來(lái)的 MongoDB 4.2 版本,還會(huì)支持分片集群的分布式事務(wù)。

          我們來(lái)看下 MongoDB 不同版本支持的功能:

          MongoDB 的不同版本

          MongoDB 的事務(wù)接口非常簡(jiǎn)單,開(kāi)發(fā)者只需要將需要保證原子性的更新序列放到一個(gè) session 的 開(kāi)始事務(wù)提交事務(wù)之間即可。下面是 Java 使用 MongoDB 事務(wù)的示例代碼:

          (2) 不支持關(guān)聯(lián)查詢。

          我們都知道 MySQL 是支持關(guān)聯(lián)查詢的,也就是可以執(zhí)行 Join 操作。比如有兩張表:用戶表和訂單表,訂單表中有用戶的 id,且性別只存在用戶表中。如果想購(gòu)買(mǎi)了手機(jī)的男性用戶,用關(guān)聯(lián)查詢,一步就能搞定。但是如果用 MongoDB,則需要查兩次,先查詢訂單表中購(gòu)買(mǎi)手機(jī)的用戶,再查詢這些用戶中哪些是男性。

          二、關(guān)系型數(shù)據(jù)的缺點(diǎn)

          2.面試官:這個(gè)項(xiàng)目為什么不用關(guān)系型數(shù)據(jù)庫(kù)?關(guān)系型數(shù)據(jù)庫(kù)有哪些缺點(diǎn)?

          順著面試官的思路,可以知道面試官想問(wèn)的是關(guān)系型數(shù)據(jù)庫(kù)有哪些不足之處。

          關(guān)系型數(shù)據(jù)庫(kù)的不足之處

          (1)存儲(chǔ)的是行記錄。

          不能存儲(chǔ)數(shù)組、嵌套字段等格式的數(shù)據(jù)。

          (2)擴(kuò)展表結(jié)構(gòu)不方便

          操作不存在的列會(huì)報(bào)錯(cuò),而增加列又需要執(zhí)行 SQL 語(yǔ)句才行。而且修改時(shí)需要特別注意,因?yàn)楦卤頃r(shí)會(huì)長(zhǎng)時(shí)間鎖表,這對(duì)線上環(huán)境可能造成嚴(yán)重影響。

          (3)占用內(nèi)存高。

          關(guān)系型數(shù)據(jù)庫(kù)在對(duì)大量數(shù)據(jù)的表進(jìn)行統(tǒng)計(jì)之類(lèi)的運(yùn)算時(shí),占用內(nèi)存會(huì)很高,因?yàn)樗词怪会槍?duì)某一列進(jìn)行運(yùn)算,也會(huì)將整行數(shù)據(jù)從存儲(chǔ)設(shè)備讀入內(nèi)存。

          (4)全文搜索性能差

          類(lèi)似于 MySQL 的關(guān)系型數(shù)據(jù)庫(kù),只能用 like 進(jìn)行整表掃描的匹配,效率很低。現(xiàn)如今,有很多場(chǎng)景需要支持模糊匹配,而且必須支持高效查找。比如查詢包含關(guān)鍵字的日志信息,又或者是根據(jù)某個(gè)商品關(guān)鍵字查詢商品列表。

          針對(duì)以上的不足之處,我們這個(gè)項(xiàng)目用了兩種非關(guān)系型的數(shù)據(jù)存儲(chǔ)方案:MongoDB 和 ElasticSearch。

          三、NoSQL 的分類(lèi)和特點(diǎn)

          3.面試官:你知道的有哪些 NoSQL 數(shù)據(jù)庫(kù)?分別有什么特點(diǎn)?

          NoSQL(NoSQL = Not Only SQL ),意即"不僅僅是SQL"。

          我知道的有 Redis、MongoDB、HBase、全文搜索引擎 Elasticsearch。他們是不同的非關(guān)系型存儲(chǔ)方案。

          K-V 存儲(chǔ)型

          比如 Redis,它可以用 K-V 鍵值對(duì)的方式來(lái)存儲(chǔ)數(shù)據(jù),而存儲(chǔ)的值可以有好幾種格式,如 string、hash、list、set、bitmap 等。

          文檔存儲(chǔ)型

          比如 MongoDB,存儲(chǔ)的 JSON 格式的文檔,解決了關(guān)系型數(shù)據(jù)庫(kù)的表約束的問(wèn)題,比如查詢不存在的字段會(huì)報(bào)錯(cuò)。另外也解決了部分存儲(chǔ)格式的問(wèn)題,因JSON 可以表示數(shù)組,還可以嵌套字段存儲(chǔ)。

          列式存儲(chǔ)型

          比如 HBase,按照列來(lái)存儲(chǔ)數(shù)據(jù),解決了大數(shù)據(jù)場(chǎng)景下的 I/O 問(wèn)題。

          關(guān)系型數(shù)據(jù)庫(kù)按照來(lái)存儲(chǔ)數(shù)據(jù),所以稱(chēng)作行式數(shù)據(jù)庫(kù)。按照來(lái)存儲(chǔ)有以下優(yōu)勢(shì):

          • 讀一行數(shù)據(jù)就能讀取到多個(gè)列,只需要一次磁盤(pán)操作就能把多個(gè)列的數(shù)據(jù)讀取到內(nèi)存中。
          • 寫(xiě)一行數(shù)據(jù)可以對(duì)多個(gè)列進(jìn)行寫(xiě)操作,保證了行數(shù)據(jù)的原子性和一致性。而對(duì)列式存儲(chǔ)的多列寫(xiě)操作,可能會(huì)導(dǎo)致有些列成功,有些失敗,產(chǎn)生數(shù)據(jù)的不一致。

          全文搜索引擎

          這個(gè)用到的最多的地方就是日志系統(tǒng),還有搜索商品信息等類(lèi)似場(chǎng)景。如下圖所示的電商網(wǎng)站。

          搜索手機(jī)

          我們項(xiàng)目中用到日志搜索就是利用 ELK。

          Elasticsearch 就是 ELK 中的 E。Elasticsearch 就是全文搜索引擎,注意:他是一種 NoSQL 方案,并不是 NoSQL 數(shù)據(jù)庫(kù)。

          Logstash 就是 ELK 中的 L。它是 Elastic Stack 的核心產(chǎn)品之一,可用來(lái)對(duì)數(shù)據(jù)進(jìn)行聚合和處理,并將數(shù)據(jù)發(fā)送到 Elasticsearch。Logstash 是一個(gè)開(kāi)源的服務(wù)器端數(shù)據(jù)處理管道,允許您在將數(shù)據(jù)索引到 Elasticsearch 之前同時(shí)從多個(gè)來(lái)源采集數(shù)據(jù),并對(duì)數(shù)據(jù)進(jìn)行充實(shí)和轉(zhuǎn)換。

          Kibana 就是 ELK 中的  K。是一款適用于 Elasticsearch 的數(shù)據(jù)可視化和管理工具,可以提供實(shí)時(shí)的直方圖、線性圖等。

          如下圖所示:

          搜索日志

          傳統(tǒng)的關(guān)系型的數(shù)據(jù)庫(kù)主要是通過(guò)索引來(lái)進(jìn)行快速查詢,但如果放在全文搜索的場(chǎng)景下,就行不通了。

          我們來(lái)看看為什么關(guān)系型數(shù)據(jù)庫(kù)很難做到高效的全文搜索:

          • 因?yàn)樵谌乃阉髦校阉鞯臈l件是可以隨意排列組合的,比如字段 A、B、C,可以排列成 6 種,如果要用索引來(lái)支持快速查詢的話,則需要?jiǎng)?chuàng)建多個(gè)索引,這是非常麻煩的,同時(shí),多個(gè)索引對(duì)數(shù)據(jù)的插入效率也是有影響的。
          • 模糊匹配只能用 like 查詢,而 like 查詢是整表掃描,效率是非常低的。

          之前我寫(xiě)過(guò)一篇 Elasticsearch 原理的:《別只會(huì)搜日志了,求你懂點(diǎn)原理吧》,通過(guò)倒排索引實(shí)現(xiàn)高效的全文檢索。下面舉個(gè)倒排索引的例子給大家看看:

          假如數(shù)據(jù)庫(kù)有如下電影記錄

          1-大話西游

          2-大話西游外傳

          3-解析大話西游

          4-西游降魔外傳

          5-夢(mèng)幻西游獨(dú)家解析

          分詞,將整句分拆為單詞

          序號(hào)保存到 ES 的詞對(duì)應(yīng)的電影記錄序號(hào)
          A西游1,2, 3,4, 5
          B大話1,2, 3
          C外傳2,4, 5
          D解析3,5
          E降魔4
          F夢(mèng)幻5
          G獨(dú)家5

          檢索:獨(dú)家大話西游

          獨(dú)家大話西游 拆分成 獨(dú)家大話、西游

          ES 中 A、B、G 記錄 都有這三個(gè)詞的其中一種, 所以 1,2, 3,4, 5 號(hào)記錄都有相關(guān)的詞被命中。

          1 號(hào)記錄命中 2 次, A、B 中都有 ( 命中 2 次 ) ,而且 1 號(hào)記錄有 2 個(gè)詞,相關(guān)性得分:2 次/2 個(gè)詞=1

          2 號(hào)記錄命中 2 個(gè)詞 A、B 中的都有 ( 命中 2 次 ) ,而且 2 號(hào)記錄有 2 個(gè)詞,相關(guān)性得分:2 次/3 個(gè)詞= 0.67

          3 號(hào)記錄命中 2 個(gè)詞 A、B 中的都有 ( 命中 2 次 ) ,而且 3 號(hào)記錄有 2 個(gè)詞,相關(guān)性得分:2 次/3 個(gè)詞= 0.67

          4 號(hào)記錄命中 2 個(gè)詞 A 中有 ( 命中 1 次 ) ,而且 4 號(hào)記錄有 3 個(gè)詞,相關(guān)性得分:1 次/3 個(gè)詞= 0.33

          5 號(hào)記錄命中 2 個(gè)詞 A 中有 ( 命中 2 次 ) ,而且 4 號(hào)記錄有 4 個(gè)詞,相關(guān)性得分:2 次/4 個(gè)詞= 0.5

          所以檢索出來(lái)的記錄順序如下

          1-大話西游 ( 關(guān)性得分:1 )

          2-大話西游外傳 ( 相關(guān)性得分:0.67 )

          3-解析大話西游 ( 相關(guān)性得分:0.67 )

          5-夢(mèng)幻西游獨(dú)家解析 ( 相關(guān)性得分:0.5 )

          4-西游降魔 ( 關(guān)性得分:0.33 )

          Elasticsearch 與 mysql 的對(duì)比

          序號(hào)MysqlElasticsearch
          1Mysql 服務(wù)ES 集群服務(wù)
          2數(shù)據(jù)庫(kù) Database索引 Index
          3表 Table類(lèi)型 Type
          4記錄 Records ( 一行行記錄 )文檔 Document ( JSON 格式 )

          另外的 NoSQL 還有圖形數(shù)據(jù)庫(kù),這里不做展開(kāi)。

          關(guān)系型和 NoSQL 怎么選?

          4.面試官:關(guān)系型和 NoSQL 怎么選呢?

          關(guān)系型和NoSQL數(shù)據(jù)庫(kù)的選型,考慮幾個(gè)指標(biāo),數(shù)據(jù)量、并發(fā)量、實(shí)時(shí)性、一致性要求、讀寫(xiě)分離、安全性、運(yùn)維性等。根據(jù)這些指標(biāo),軟件系統(tǒng)可分成幾類(lèi)。

          • 管理型系統(tǒng),如運(yùn)營(yíng)類(lèi)系統(tǒng),首選關(guān)系型。
          • 大流量系統(tǒng),且多字段、數(shù)據(jù)量增長(zhǎng)快,首選 NoSQL。
          • 日志型系統(tǒng),首選 Elasticsearch
          • 搜索型系統(tǒng),指站內(nèi)搜索,非通用搜索,如商品搜索,首選 Elasticsearch。
          • 事務(wù)型系統(tǒng),如庫(kù)存、交易、記賬,選關(guān)系型+緩存+一致性協(xié)議。
          • 離線計(jì)算,如大量數(shù)據(jù)分析,首選列式數(shù)據(jù)庫(kù)。
          • 實(shí)時(shí)計(jì)算,如實(shí)時(shí)監(jiān)控,可以選時(shí)序數(shù)據(jù)庫(kù),或列式數(shù)據(jù)庫(kù)。

          面試結(jié)果:技術(shù)負(fù)責(zé)人覺(jué)得還行,但 HR 今天不在,等 HR 下次通知吧。后續(xù)就沒(méi)通知了。


          參考資料: 

          https://mongoing.com/archives/5560 

          https://time.geekbang.org/column/article/8377 

          https://dzone.com/articles/history-databases-%E2%80%9Cno-tation%E2%80%9D 

          https://www.runoob.com/mongodb/nosql.html


          最后給大家分享我寫(xiě)的SQL兩件套:《SQL基礎(chǔ)知識(shí)第二版》《SQL高級(jí)知識(shí)第二版》的PDF電子版。里面有各個(gè)語(yǔ)法的解釋、大量的實(shí)例講解和批注等等,非常通俗易懂,方便大家跟著一起來(lái)實(shí)操。


          有需要的讀者可以下載學(xué)習(xí),在下面的公眾號(hào)「數(shù)據(jù)前線」(非本號(hào))后臺(tái)回復(fù)關(guān)鍵字:SQL,就行

          數(shù)據(jù)前線


          后臺(tái)回復(fù)關(guān)鍵字:1024,獲取一份精心整理的技術(shù)干貨

          后臺(tái)回復(fù)關(guān)鍵字:進(jìn)群,帶你進(jìn)入高手如云的交流群

          記得幫忙點(diǎn)「」和「在看」↓

          謝謝啦

          瀏覽 171
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  能看的黄色视频 | 中文字幕无码在线 | 国产av线路一高清 | 日韩永久在线 | 激情伊人五月天 |