天天看點

為什麼你精通CRUD,卻搞不懂資料庫的基本原理?

原創聲明

本文作者:黃小斜

轉載請務必在文章開頭注明出處和作者。

本文思維導圖

為什麼你精通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必知必會

為什麼你精通CRUD,卻搞不懂資料庫的基本原理?

​​

這本書主要是講解sql語句怎麼寫,畢竟資料庫最重要的一點就是要熟練地使用sql語句,當然這本書也可以當做工具書來使用。

2 深入淺出MySQL

為什麼你精通CRUD,卻搞不懂資料庫的基本原理?

這本書适合作為MySQL的學習書籍,當你有了一定的MySQL使用經驗後,可以看看它,該書從資料庫的基礎、開發、優化、管理維護和架構5個方面對MySQL進行了詳細的介紹,講的不算特别深,但是足夠我們使用了。這本書我也隻看了一部分。

3 MySQL技術内幕:innodb存儲引擎

為什麼你精通CRUD,卻搞不懂資料庫的基本原理?

看完上面那本書以後,對MySQL算是比較熟悉了,不過對于面試中常考的innodb引擎,還是推薦一下這本書把,專門講解了innodb存儲引擎的相關内容。我還沒有細看,但是内容足夠你學好innodb了。

4 高性能Mysql

為什麼你精通CRUD,卻搞不懂資料庫的基本原理?

這本書可以說是很厚了,更适合DBA拜讀,講的太詳細了,打擾了。

微信公衆号【程式員黃小斜】

緻力于讓自學程式設計這件事變得更簡單,授人以魚也要授人以漁。作者自學程式設計轉行網際網路,目前是阿裡巴巴Java工程師,專注于分享程式員前沿技術幹貨和程式設計學習心得,期待你的關注,和我們一起進步! 

文中所提到的電子書都可以免費領取,在我的公衆号背景回複“計算機網絡”即可領取對應的下載下傳位址。

為什麼你精通CRUD,卻搞不懂資料庫的基本原理?