2020別再說(shuō)你了解數(shù)據(jù)庫(kù)了,你搞清楚這些問題了嗎?

程序員中一直有一個(gè)段子廣為流傳:大不了我們“刪庫(kù)跑路”

由此可見作為一個(gè)程序員,不了解數(shù)據(jù)庫(kù)怎么能行,那么數(shù)據(jù)庫(kù)到底是個(gè)啥呢,作為一個(gè)Java工程師,平時(shí)和數(shù)據(jù)庫(kù)打交道著實(shí)不少,所謂的CRUD其實(shí)就是對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查的操作。

根據(jù)百度百科的介紹,數(shù)據(jù)庫(kù)是“按照數(shù)據(jù)結(jié)構(gòu)來(lái)組織、存儲(chǔ)和管理數(shù)據(jù)的倉(cāng)庫(kù)”。是一個(gè)長(zhǎng)期存儲(chǔ)在計(jì)算機(jī)內(nèi)的、有組織的、有共享的、統(tǒng)一管理的數(shù)據(jù)集合。

數(shù)據(jù)庫(kù)是以一定方式儲(chǔ)存在一起、能與多個(gè)用戶共享、具有盡可能小的冗余度、與應(yīng)用程序彼此獨(dú)立的數(shù)據(jù)集合,可視為電子化的文件柜——存儲(chǔ)電子文件的處所,用戶可以對(duì)文件中的數(shù)據(jù)進(jìn)行新增、查詢、更新、刪除等操作。

是不是沒聽懂,好吧,簡(jiǎn)單來(lái)說(shuō),像MySQL這樣的數(shù)據(jù)庫(kù),就是用于存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù)的,比如一個(gè)學(xué)生的信息數(shù)據(jù),一個(gè)商品的數(shù)據(jù),或者是一個(gè)學(xué)生購(gòu)買商品的消費(fèi)數(shù)據(jù)。

聯(lián)想到平時(shí)我們經(jīng)常使用的Excel,其實(shí)和數(shù)據(jù)庫(kù)挺像的,數(shù)據(jù)庫(kù)其實(shí)就是一個(gè)表格,里面有很多的數(shù)據(jù)類型,比如字符串,比如數(shù)字,再比如長(zhǎng)文本等等。

而這類數(shù)據(jù)庫(kù)也叫關(guān)系型數(shù)據(jù)庫(kù),典型代表就是MySQL。

再看看百度百科的介紹,關(guān)系型數(shù)據(jù)庫(kù),是指采用了關(guān)系模型來(lái)組織數(shù)據(jù)的數(shù)據(jù)庫(kù),其以行和列的形式存儲(chǔ)數(shù)據(jù),以便于用戶理解,關(guān)系型數(shù)據(jù)庫(kù)這一系列的行和列被稱為表,一組表組成了數(shù)據(jù)庫(kù)。用戶通過查詢來(lái)檢索數(shù)據(jù)庫(kù)中的數(shù)據(jù),而查詢是一個(gè)用于限定數(shù)據(jù)庫(kù)中某些區(qū)域的執(zhí)行代碼。關(guān)系模型可以簡(jiǎn)單理解為二維表格模型,而一個(gè)關(guān)系型數(shù)據(jù)庫(kù)就是由二維表及其之間的關(guān)系組成的一個(gè)數(shù)據(jù)組織。

除了關(guān)系型數(shù)據(jù)庫(kù)之外,近些年來(lái)還有很多nosql(not only sql)數(shù)據(jù)庫(kù)在興起,比如MongoDB,以及圖數(shù)據(jù)庫(kù)、列式數(shù)據(jù)庫(kù)等等,這些數(shù)據(jù)庫(kù)對(duì)于新手程序員來(lái)說(shuō)用的并不多,所以本文我們只討論關(guān)于關(guān)系型數(shù)據(jù)庫(kù)的內(nèi)容。

關(guān)系型數(shù)據(jù)庫(kù)是我們程序員平時(shí)用的最多,也最簡(jiǎn)單易上手的數(shù)據(jù)庫(kù)類型,所以,學(xué)習(xí)數(shù)據(jù)庫(kù)一般也從MySQL這類關(guān)系型數(shù)據(jù)庫(kù)入手,一來(lái)它簡(jiǎn)單好學(xué),二來(lái)它是免費(fèi)的。

學(xué)習(xí)數(shù)據(jù)庫(kù),先從SQL入手

說(shuō)到MySQL,就不得不談?wù)凷QL了,sql,按照百科的說(shuō)法是這樣的

結(jié)構(gòu)化查詢語(yǔ)言(Structured Query Language)簡(jiǎn)稱SQL,是一種特殊目的的編程語(yǔ)言,是一種數(shù)據(jù)庫(kù)查詢和程序設(shè)計(jì)語(yǔ)言,用于存取數(shù)據(jù)以及查詢、更新和管理關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)。

對(duì)于不同的數(shù)據(jù)庫(kù),sql的寫法可能有一些差異,但是大致都是相同的,就拿MySQL來(lái)說(shuō),平時(shí)我們用到最多的就是select、update、delete和insert了,這類操作統(tǒng)稱為數(shù)據(jù)操縱語(yǔ)言DML(Data Manipulation Language),用戶通過它可以實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的基本操作。

當(dāng)然還有操作數(shù)據(jù)庫(kù)和表的一些ddl,數(shù)據(jù)庫(kù)模式定義語(yǔ)言DDL(Data Definition Language),是用于描述數(shù)據(jù)庫(kù)中要存儲(chǔ)的現(xiàn)實(shí)世界實(shí)體的語(yǔ)言。 簡(jiǎn)單來(lái)說(shuō),ddl其實(shí)就是用來(lái)執(zhí)行建表,刪表,更改表結(jié)構(gòu)等操作的

以前我的sql寫的并不多,畢竟簡(jiǎn)單的增刪改查并不需要多復(fù)雜的sql技巧,最多就是做一下表連接。

再到后來(lái),我開始做一些項(xiàng)目,接觸了ORM的一些框架,比如hibernate和mybatis,這些框架甚至可以讓你完全不寫sql,只要調(diào)用一些增刪改查的API即可,這讓我很長(zhǎng)一段時(shí)間都忽略了SQL的重要性。

其實(shí)學(xué)習(xí)sql最復(fù)雜的地方并不是一些高級(jí)用法,而是在于實(shí)際場(chǎng)景中的應(yīng)用和優(yōu)化。兩條sql,可能因?yàn)楹?jiǎn)單的差異就會(huì)有很大的性能差距,差異點(diǎn)可能是,比如有沒有走到索引,是否是全表掃描,又或者走到了哪個(gè)索引,而這樣的性能分析只有在實(shí)際的場(chǎng)景里才有意義。

當(dāng)然了,對(duì)于新手來(lái)說(shuō),學(xué)習(xí)sql的語(yǔ)法是放在第一位的,然后才能逐漸過渡到會(huì)使用,會(huì)優(yōu)化,會(huì)分析。

數(shù)據(jù)庫(kù)基本原理

學(xué)習(xí)數(shù)據(jù)庫(kù),你需要先打好基礎(chǔ),數(shù)據(jù)庫(kù)原理是計(jì)算機(jī)科班的一門必修課,非科班的我選擇的是自學(xué),我當(dāng)時(shí)也是拿著那本大學(xué)教材《數(shù)據(jù)庫(kù)系統(tǒng)概論》來(lái)自學(xué)的。

教材這種東西,肯定還是偏理論的一點(diǎn),我們要了解的內(nèi)容主要包含幾個(gè)方面

1、數(shù)據(jù)庫(kù)模型有哪些:包括層次模型、網(wǎng)狀模型和關(guān)系模型,我們所用的關(guān)系型數(shù)據(jù)庫(kù)就是基于關(guān)系模型實(shí)現(xiàn)的。

2、關(guān)系數(shù)據(jù)庫(kù)的基礎(chǔ)和sql:了解關(guān)系數(shù)據(jù)庫(kù)的基本概念,了解sql的基本使用方法,至少CRUD和一些常見用法要搞懂

3、數(shù)據(jù)庫(kù)的安全性和完整性,這兩部分內(nèi)容其實(shí)理論的東西比較枯燥,實(shí)際上對(duì)應(yīng)到實(shí)際場(chǎng)景中,安全性就是要保護(hù)數(shù)據(jù)的安全,包括權(quán)限控制和數(shù)據(jù)備份,而完整性則是通過一些約定和規(guī)范來(lái)限制數(shù)據(jù)庫(kù)的存儲(chǔ)內(nèi)容,比如我們可以用主鍵、唯一鍵、非空等要求來(lái)限制字段的取值。

4、關(guān)系數(shù)據(jù)理論 這部分內(nèi)容很有意思,也比較復(fù)雜,講到了數(shù)據(jù)庫(kù)的范式理論,從一范式到四范式,各有各的用法和要求,某互聯(lián)網(wǎng)公司“第四范式”就是用這個(gè)概念來(lái)命名的。

5、事務(wù)和鎖 最后一部分內(nèi)容,就是數(shù)據(jù)庫(kù)的兩個(gè)重要組成部分,事務(wù)和鎖,事務(wù)可以保證一組數(shù)據(jù)庫(kù)操作的ACID特性,非常適用于需要數(shù)據(jù)一致性的場(chǎng)景,而數(shù)據(jù)庫(kù)的鎖不但是實(shí)現(xiàn)事務(wù)的基礎(chǔ),還可以靈活地適用于不同的數(shù)據(jù)庫(kù)應(yīng)用場(chǎng)景,我們還可以通過sql語(yǔ)句來(lái)完成加鎖和釋放,對(duì)于并發(fā)場(chǎng)景尤其管用。

MySQL的實(shí)現(xiàn)原理

學(xué)習(xí)完了數(shù)據(jù)庫(kù)基礎(chǔ)之后,接下來(lái)就該學(xué)習(xí)MySQL了,畢竟很多時(shí)候我們的數(shù)據(jù)庫(kù)應(yīng)用就是MySQL。

其實(shí)MySQL里的很多知識(shí)點(diǎn)和我們上面提到的數(shù)據(jù)庫(kù)基礎(chǔ)大同小異,而回到MySQL的實(shí)現(xiàn)層,我們就得來(lái)看看MySQL的存儲(chǔ)引擎了。

MySQL的存儲(chǔ)引擎分為innodb和myisam,相信大家對(duì)于這兩個(gè)引擎區(qū)別的面試題看了也不少,比如innodb支持事務(wù),支持行級(jí)鎖,而myisam不支持。

由于現(xiàn)在innodb基本上是主流,所以我們討論MySQL的時(shí)候基本上就是在討論innodb。對(duì)于MySQL的實(shí)現(xiàn)原理,我認(rèn)為大概有這么一些內(nèi)容需要我們?nèi)W(xué)習(xí)。

首先,我們了解MySQL里有哪些數(shù)據(jù)類型,一般的用法如何,然后,嘗試用MySQL去跑一些sql語(yǔ)句,建庫(kù)建表,加索引加主鍵,總之,這些實(shí)踐能幫助你更好地學(xué)習(xí)上述內(nèi)容。

想要更好地了解MySQL的原理,我們就必須要了解MySQL的整體架構(gòu)

image

客戶端

也就是我們經(jīng)常用的可視化工具,比如Navicat for MySQL

服務(wù)端

就是我們安裝的MySQL程序,其實(shí)打開它它就是一個(gè)MySQL的服務(wù)端進(jìn)程

sql執(zhí)行層

sql執(zhí)行層主要負(fù)責(zé)解析執(zhí)行sql,里面包含了很多復(fù)雜的組成部分,比如解釋器,分析器,優(yōu)化器等等,執(zhí)行層會(huì)生成一個(gè)sql的執(zhí)行計(jì)劃,這個(gè)計(jì)劃也經(jīng)常是我們分析sql性能的一個(gè)重要參考內(nèi)容

存儲(chǔ)引擎層

存儲(chǔ)引擎層是innodb了,比如數(shù)據(jù)要如組織和存放,索引要如何建立和管理等等,加鎖怎么加,事務(wù)如何實(shí)現(xiàn),都是這一層要考慮的內(nèi)容。

文件系統(tǒng)層

存儲(chǔ)引擎的下一層就是文件系統(tǒng)了,數(shù)據(jù)庫(kù)的數(shù)據(jù)如何和文件系統(tǒng)進(jìn)行交互,就是這一層要做的事情了。

索引

不得不說(shuō),索引絕對(duì)是數(shù)據(jù)庫(kù)中最經(jīng)??疾欤键c(diǎn)也最多的內(nèi)容了。

比如給你一條sql,那么它能否命中索引,能命中哪些索引,如果想要命中某個(gè)索引,你應(yīng)該如何修改,這種問題面試時(shí)是不是經(jīng)??吹?,變來(lái)變?nèi)ミ@么多題型,其實(shí)面試官就是想考察你對(duì)于索引的理解。

還有就是,索引的數(shù)據(jù)結(jié)構(gòu),一樣是非常熱門的考點(diǎn)之一,索引其實(shí)是基于B+樹來(lái)實(shí)現(xiàn)的,不知道b+樹是啥,請(qǐng)回去看數(shù)據(jù)結(jié)構(gòu)。

簡(jiǎn)單來(lái)說(shuō),它是一種多路搜索樹,致力于更短的時(shí)間來(lái)完成數(shù)據(jù)檢索,因?yàn)樗母叨缺榷鏄湟停绕鹌胀ǖ腷樹,它的非葉節(jié)點(diǎn)只起索引作用,而葉子節(jié)點(diǎn)是順序串聯(lián)的,所以非常適合做搜索樹。

如果你理解了這一點(diǎn),那么面對(duì)此類面試題就可以更加從容一些,面試官其實(shí)就是想知道你對(duì)b+樹的了解到了什么樣的程度而已。

事務(wù)和鎖

除了索引之外,數(shù)據(jù)庫(kù)中最復(fù)雜的內(nèi)容可能就是事務(wù)和鎖了。

就拿事務(wù)的ACID特性來(lái)說(shuō),你需要了解每個(gè)大寫字母背后的實(shí)現(xiàn)原理,比如原子性是如何實(shí)現(xiàn)的,一致性是如何保證的,背后的原理是什么。

我們平時(shí)常用的事務(wù)可能就是spring里的事務(wù)模板,在事務(wù)里執(zhí)行的同庫(kù)數(shù)據(jù)庫(kù)操作,要么都成功,要么都失敗,這就是原子性。

兩個(gè)事務(wù)之間互不影響,這就是隔離性,當(dāng)然了,這里又涉及到了事務(wù)隔離級(jí)別。

事務(wù)隔離級(jí)別包括讀未提交,讀已提交,可重復(fù)讀和序列化,每個(gè)事務(wù)隔離級(jí)別都適用于某種數(shù)據(jù)庫(kù)讀寫場(chǎng)景,很多時(shí)候,我們都需要搞懂隔離級(jí)別背后的原理,才能更好地適用它。

MySQL里默認(rèn)使用可重復(fù)讀的隔離級(jí)別,這個(gè)級(jí)別基本上可以保證我們的事務(wù)按照預(yù)期執(zhí)行,在MySQL中,這個(gè)事務(wù)隔離級(jí)別甚至可以解決幻讀的問題。

在MySQL的事務(wù)背后,其實(shí)有一個(gè)隱藏的boss,那就是數(shù)據(jù)庫(kù)的鎖,很多事務(wù)的隔離級(jí)別都是通過鎖來(lái)實(shí)現(xiàn)的,比如可重復(fù)讀只要加行鎖就可以實(shí)現(xiàn)了,而幻讀則需要加上間隙鎖next-key lock來(lái)實(shí)現(xiàn)。

行級(jí)鎖和表級(jí)鎖是MySQL中的兩種鎖,表級(jí)鎖顧名思義,會(huì)直接鎖表,一次只有一個(gè)事務(wù)能夠訪問,而行級(jí)鎖其實(shí)鎖的也并非是一行,在MySQL中,這個(gè)鎖加在索引上,而這個(gè)索引對(duì)應(yīng)的數(shù)據(jù)往往不止一行,所以這個(gè)行級(jí)鎖只是理論意義上的"行級(jí)鎖"

數(shù)據(jù)庫(kù)事務(wù)的四原則

數(shù)據(jù)庫(kù)事務(wù)ACID四大原則:

A代表Atomicity,即原子性。

C表示Consistency,即一致性。

I表示Isolation,即隔離性。

D表示Durability,即持久性。

這四個(gè)原則了解過數(shù)據(jù)庫(kù)的應(yīng)該都如雷貫耳??墒钦嬲嬖嚨臅r(shí)候被問起來(lái),能一個(gè)不落說(shuō)得上來(lái),并且講得清楚原委的就不多了。我覺得主要是因?yàn)槲覀兊姆g過于文雅,不像英文那么直觀,所以很難顧名思義。另一個(gè)原因是我們?cè)趯W(xué)習(xí)的時(shí)候理解不夠深入,只知道原因,不知道原因的究竟。所謂知其然,不知其所以然。

image

最后擺上學(xué)習(xí)資料

image

以上內(nèi)容都是我自己的一些感想,分享出來(lái)歡迎大家指正,順便求一波關(guān)注

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容