原創聲明 本文作者:黃小斜 轉載請務必在文章開頭註明出處和作者。 本文思維導圖 資料庫和關係型資料庫 作為一個程式員,不瞭解資料庫怎麼能行,那麼資料庫到底是個啥呢,作為一個Java工程師,平時和資料庫打交道著實不少,所謂的CRUD其實就是對資料庫進行增刪改查的操作。 根據百度百科的介紹,資料庫是 ...
原創聲明
本文作者:黃小斜
轉載請務必在文章開頭註明出處和作者。
本文思維導圖
資料庫和關係型資料庫
作為一個程式員,不瞭解資料庫怎麼能行,那麼資料庫到底是個啥呢,作為一個Java工程師,平時和資料庫打交道著實不少,所謂的CRUD其實就是對資料庫進行增刪改查的操作。
根據百度百科的介紹,資料庫是“按照數據結構來組織、存儲和管理數據的倉庫”。是一個長期存儲在電腦內的、有組織的、有共用的、統一管理的數據集合。
資料庫是以一定方式儲存在一起、能與多個用戶共用、具有儘可能小的冗餘度、與應用程式彼此獨立的數據集合,可視為電子化的文件櫃——存儲電子文件的處所,用戶可以對文件中的數據進行新增、查詢、更新、刪除等操作。
是不是沒聽懂,好吧,簡單來說,像MySQL這樣的資料庫,就是用於存儲結構化數據的,比如一個學生的信息數據,一個商品的數據,或者是一個學生購買商品的消費數據。
聯想到平時我們經常使用的Excel,其實和資料庫挺像的,資料庫其實就是一個表格,裡面有很多的數據類型,比如字元串,比如數字,再比如長文本等等。
而這類資料庫也叫關係型資料庫,典型代表就是MySQL。
再看看百度百科的介紹,關係型資料庫,是指採用了關係模型來組織數據的資料庫,其以行和列的形式存儲數據,以便於用戶理解,關係型資料庫這一系列的行和列被稱為表,一組表組成了資料庫。用戶通過查詢來檢索資料庫中的數據,而查詢是一個用於限定資料庫中某些區域的執行代碼。關係模型可以簡單理解為二維表格模型,而一個關係型資料庫就是由二維表及其之間的關係組成的一個數據組織。
除了關係型資料庫之外,近些年來還有很多nosql(not only sql)資料庫在興起,比如MongoDB,以及圖資料庫、列式資料庫等等,這些資料庫對於新手程式員來說用的並不多,所以本文我們只討論關於關係型資料庫的內容。
關係型資料庫是我們程式員平時用的最多,也最簡單易上手的資料庫類型,所以,學習資料庫一般也從MySQL這類關係型資料庫入手,一來它簡單好學,二來它是免費的。
我的資料庫學習歷程
我第一次聽說“資料庫”這個詞還是在大學的時候,那時候正值大家找工作,有一個同學和我們分享自己的求職經驗,據他所說,每個公司都會考察你的資料庫知識,學好了資料庫,面試什麼公司都不怕。
當時我還覺得挺玄乎的,不過我們學校確實沒來什麼大公司,我對此半信半疑,至於到底是不是這樣,後來也就沒再追究了。
第二次接觸資料庫,是在學習Java的時候,記得當初自己跟著一個小教程,下載安裝了MySQL,然後從網上下載了demo代碼,用當時先進的開發工具eclipse跑通了別人家的代碼,其實就是增刪改查。
只不過當時對這些東西也沒啥概念,後來又下載了一個db的可視化工具,可以更方便地瞭解自己的資料庫里到底都有啥。
再到後來,我開始慢慢接觸項目實戰,使用資料庫的時間也越來越長,自以為對於資料庫的理解還算可以,直到我真正地接觸了資料庫相關的面試題,才讓我發現自己對於資料庫的理解是多麼的膚淺。
那個時候,我只懂寫一些簡單的crud,甚至連內外連接、group by和count等一些簡單的sql用法都不瞭解,除此之外,我對於資料庫的一些原理性內容幾乎也是一竅不通的,比如資料庫的索引、事務、鎖機制,我統統不知道,更別談如何回答相關的面試題了。
於是,我開始意識到學習資料庫原理是多麼重要的一件事情,我開始看資料庫方面的書籍,從最基礎的資料庫教材,再到MySQL的原理性內容,再到mybatis這類orm框架的實現,我都逐漸地開始學習和瞭解,直到我能夠對大部分的資料庫面試題都較好地掌握。
而現在,我在一個每天要處理海量數據的公司里工作,對於數據方面的學習已經不僅僅停留在資料庫了,我還要接觸數據倉庫、分散式資料庫以及各種大數據的應用場景,學習數據知識的道路看來短時間內是走不完了。
學習資料庫,先從SQL入手
說到MySQL,就不得不談談SQL了,sql,按照百科的說法是這樣的
結構化查詢語言(Structured Query Language)簡稱SQL,是一種特殊目的的編程語言,是一種資料庫查詢和程式設計語言,用於存取數據以及查詢、更新和管理關係資料庫系統。
對於不同的資料庫,sql的寫法可能有一些差異,但是大致都是相同的,就拿MySQL來說,平時我們用到最多的就是select、update、delete和insert了,這類操作統稱為數據操縱語言DML(Data Manipulation Language),用戶通過它可以實現對資料庫的基本操作。
當然還有操作資料庫和表的一些ddl,資料庫模式定義語言DDL(Data Definition Language),是用於描述資料庫中要存儲的現實世界實體的語言。 簡單來說,ddl其實就是用來執行建表,刪表,更改表結構等操作的
以前我的sql寫的並不多,畢竟簡單的增刪改查並不需要多複雜的sql技巧,最多就是做一下表連接。
再到後來,我開始做一些項目,接觸了ORM的一些框架,比如hibernate和mybatis,這些框架甚至可以讓你完全不寫sql,只要調用一些增刪改查的API即可,這讓我很長一段時間都忽略了SQL的重要性。
其實學習sql最複雜的地方並不是一些高級用法,而是在於實際場景中的應用和優化。兩條sql,可能因為簡單的差異就會有很大的性能差距,差異點可能是,比如有沒有走到索引,是否是全表掃描,又或者走到了哪個索引,而這樣的性能分析只有在實際的場景里才有意義。
當然了,對於新手來說,學習sql的語法是放在第一位的,然後才能逐漸過渡到會使用,會優化,會分析。
關於資料庫的那些面試題
想要真正學好資料庫,搞定面試題中的相關問題,那你就必須要搞懂資料庫的基本原理。
如果你不相信,那我隨便舉幾個面試題常見的題型,比如”資料庫事務的ACID是什麼意思”、“資料庫中有哪些鎖”、“資料庫的索引用的是什麼數據結構”
上面幾道題算是簡易版的,在平常的面試中也經常能夠看到,就算你只是背一背答案,可能也多少能答對一些,那麼如果再進一步,考察一下資料庫的原理性知識,恐怕就沒這麼簡單了。
舉個慄子“資料庫事務的ACID是如何實現的”,“資料庫中有哪些鎖,分別是如何實現的,如何使用”、“資料庫中的索引是如何實現的,何時命中索引,何時不能,為什麼“
是不是感覺難度一下子就上來了。畢竟深入到原理性的東西,懂的人就越來越少了。除此之外,還有很多進階的面試題,更多時候會結合實際場景來考察。
比如考察你對MySQL存儲引擎innodb的理解,對於sql優化的理解 ,以及對於分散式場景下資料庫能力的應用,比如分散式鎖,分散式事務,以及分庫分表的一些問題。
知道了面試題大概都考啥之後,接下來我們要做的就是找到癥結所在,然後一一擊破
資料庫基本原理
學習資料庫,你需要先打好基礎,資料庫原理是電腦科班的一門必修課,非科班的我選擇的是自學,我當時也是拿著那本大學教材《資料庫系統概論》來自學的。
教材這種東西,肯定還是偏理論的一點,我們要瞭解的內容主要包含幾個方面
1、資料庫模型有哪些:包括層次模型、網狀模型和關係模型,我們所用的關係型資料庫就是基於關係模型實現的。
2、關係資料庫的基礎和sql:瞭解關係資料庫的基本概念,瞭解sql的基本使用方法,至少CRUD和一些常見用法要搞懂
3、資料庫的安全性和完整性,這兩部分內容其實理論的東西比較枯燥,實際上對應到實際場景中,安全性就是要保護數據的安全,包括許可權控制和數據備份,而完整性則是通過一些約定和規範來限制資料庫的存儲內容,比如我們可以用主鍵、唯一鍵、非空等要求來限制欄位的取值。
4、關係數據理論 這部分內容很有意思,也比較複雜,講到了資料庫的範式理論,從一範式到四範式,各有各的用法和要求,某互聯網公司“第四範式”就是用這個概念來命名的。
5、事務和鎖 最後一部分內容,就是資料庫的兩個重要組成部分,事務和鎖,事務可以保證一組資料庫操作的ACID特性,非常適用於需要數據一致性的場景,而資料庫的鎖不但是實現事務的基礎,還可以靈活地適用於不同的資料庫應用場景,我們還可以通過sql語句來完成加鎖和釋放,對於併發場景尤其管用。
MySQL的實現原理
學習完了資料庫基礎之後,接下來就該學習MySQL了,畢竟很多時候我們的資料庫應用就是MySQL。
其實MySQL里的很多知識點和我們上面提到的資料庫基礎大同小異,而回到MySQL的實現層,我們就得來看看MySQL的存儲引擎了。
MySQL的存儲引擎分為innodb和myisam,相信大家對於這兩個引擎區別的面試題看了也不少,比如innodb支持事務,支持行級鎖,而myisam不支持。
由於現在innodb基本上是主流,所以我們討論MySQL的時候基本上就是在討論innodb。對於MySQL的實現原理,我認為大概有這麼一些內容需要我們去學習。
首先,我們瞭解MySQL里有哪些數據類型,一般的用法如何,然後,嘗試用MySQL去跑一些sql語句,建庫建表,加索引加主鍵,總之,這些實踐能幫助你更好地學習上述內容。
想要更好地瞭解MySQL的原理,我們就必須要瞭解MySQL的整體架構,一般來說,MySQL從上到下可以分為這麼幾層
客戶端
也就是我們經常用的可視化工具,比如Navicat for MySQL
服務端
就是我們安裝的MySQL程式,其實打開它它就是一個MySQL的服務端進程
sql執行層
sql執行層主要負責解析執行sql,裡面包含了很多複雜的組成部分,比如解釋器,分析器,優化器等等,執行層會生成一個sql的執行計劃,這個計劃也經常是我們分析sql性能的一個重要參考內容
存儲引擎層
存儲引擎層是innodb了,比如數據要如組織和存放,索引要如何建立和管理等等,加鎖怎麼加,事務如何實現,都是這一層要考慮的內容。
文件系統層
存儲引擎的下一層就是文件系統了,資料庫的數據如何和文件系統進行交互,就是這一層要做的事情了。
索引
不得不說,索引絕對是資料庫中最經常考察,考點也最多的內容了。
比如給你一條sql,那麼它能否命中索引,能命中哪些索引,如果想要命中某個索引,你應該如何修改,這種問題面試時是不是經常看到,變來變去這麼多題型,其實面試官就是想考察你對於索引的理解。
還有就是,索引的數據結構,一樣是非常熱門的考點之一,索引其實是基於B+樹來實現的,不知道b+樹是啥,請回去看數據結構。
簡單來說,它是一種多路搜索樹,致力於更短的時間來完成數據檢索,因為它的高度比二叉樹要低,而比起普通的b樹,它的非葉節點只起索引作用,而葉子節點是順序串聯的,所以非常適合做搜索樹。
如果你理解了這一點,那麼面對此類面試題就可以更加從容一些,面試官其實就是想知道你對b+樹的瞭解到了什麼樣的程度而已。
事務和鎖
除了索引之外,資料庫中最複雜的內容可能就是事務和鎖了。
就拿事務的ACID特性來說,你需要瞭解每個大寫字母背後的實現原理,比如原子性是如何實現的,一致性是如何保證的,背後的原理是什麼。
我們平時常用的事務可能就是spring里的事務模板,在事務里執行的同庫資料庫操作,要麼都成功,要麼都失敗,這就是原子性。
兩個事務之間互不影響,這就是隔離性,當然了,這裡又涉及到了事務隔離級別。
事務隔離級別包括讀未提交,讀已提交,可重覆讀和序列化,每個事務隔離級別都適用於某種資料庫讀寫場景,很多時候,我們都需要搞懂隔離級別背後的原理,才能更好地適用它。
MySQL里預設使用可重覆讀的隔離級別,這個級別基本上可以保證我們的事務按照預期執行,在MySQL中,這個事務隔離級別甚至可以解決幻讀的問題。
在MySQL的事務背後,其實有一個隱藏的boss,那就是資料庫的鎖,很多事務的隔離級別都是通過鎖來實現的,比如可重覆讀只要加行鎖就可以實現了,而幻讀則需要加上間隙鎖next-key lock來實現。
行級鎖和表級鎖是MySQL中的兩種鎖,表級鎖顧名思義,會直接鎖表,一次只有一個事務能夠訪問,而行級鎖其實鎖的也並非是一行,在MySQL中,這個鎖加在索引上,而這個索引對應的數據往往不止一行,所以這個行級鎖只是理論意義上的"行級鎖"
說了這麼多,要理解MySQL的事務和鎖,還是要多看看相關的書籍和文章,理解其內部的實現原理,知其然也要知其所以然。
下麵又到了我們熟悉的資源推薦環節
推薦資源
書籍
資料庫
0 《資料庫系統概論》
資料庫原理應該是教材吧,這本書作為資料庫入門來說還是可以的,畢竟不是專門做DB的,看大厚書用處不大,這本書把資料庫的基本概念都講完了。
1 sql必知必會
這本書主要是講解sql語句怎麼寫,畢竟資料庫最重要的一點就是要熟練地使用sql語句,當然這本書也可以當做工具書來使用。
2 深入淺出MySQL
這本書適合作為MySQL的學習書籍,當你有了一定的MySQL使用經驗後,可以看看它,該書從資料庫的基礎、開發、優化、管理維護和架構5個方面對MySQL進行了詳細的介紹,講的不算特別深,但是足夠我們使用了。這本書我也只看了一部分。
3 MySQL技術內幕:innodb存儲引擎
看完上面那本書以後,對MySQL算是比較熟悉了,不過對於面試中常考的innodb引擎,還是推薦一下這本書把,專門講解了innodb存儲引擎的相關內容。我還沒有細看,但是內容足夠你學好innodb了。
4 高性能Mysql
這本書可以說是很厚了,更適合DBA拜讀,講的太詳細了,打擾了。
微信公眾號【程式員黃小斜】
致力於讓自學編程這件事變得更簡單,授人以魚也要授人以漁。作者自學編程轉行互聯網,目前是阿裡巴巴Java工程師,專註於分享程式員前沿技術乾貨和編程學習心得,期待你的關註,和我們一起進步!
文中所提到的電子書都可以免費領取,在我的公眾號後臺回覆“電腦網路”即可領取對應的下載地址。