Mysql

1、聚集索引和非聚集索引

  • 聚集索引:索引中鍵值的邏輯順序決定了表中對(duì)應(yīng)行的物理順序,且索引到的值保存了全部數(shù)據(jù);
  • 非聚集索引:索引中的鍵值的邏輯順序與表中對(duì)應(yīng)行的物理順序不一致,同時(shí),葉子節(jié)點(diǎn)不再存儲(chǔ)全數(shù)據(jù),而是僅保存索引字段和主鍵信息,如果要獲取其余數(shù)據(jù),則需要使用主鍵進(jìn)行回表操作。(因此,這里引出了覆蓋索引的必要性)

2、為什么推薦整型的自增主鍵(不使用uuid做主鍵)

  • uuid 不是整型,也不是自增
  • 自增是為了減少建樹過程中的分裂和平衡的次數(shù),提高寫入性能
  • 如果主鍵為自增 id 的話,mysql 在寫滿一個(gè)數(shù)據(jù)頁的時(shí)候,直接申請(qǐng)另一個(gè)新數(shù)據(jù)頁接著寫就可以了。
  • 如果主鍵是非自增 id,為了確保索引有序,mysql 就需要將每次插入的數(shù)據(jù)都放到合適的位置上。
  • 當(dāng)往一個(gè)快滿或已滿的數(shù)據(jù)頁中插入數(shù)據(jù)時(shí),新插入的數(shù)據(jù)會(huì)將數(shù)據(jù)頁寫滿,mysql 就需要申請(qǐng)新的數(shù)據(jù)頁,并且把上個(gè)數(shù)據(jù)頁中的部分?jǐn)?shù)據(jù)挪到新的數(shù)據(jù)頁上, 就造成了頁分裂,這個(gè)大量移動(dòng)數(shù)據(jù)的過程是會(huì)嚴(yán)重影響插入效率的。

3、Mysql中的索引結(jié)構(gòu)

  • Hash
    • 對(duì)索引的key進(jìn)行一次hash計(jì)算就可以定位出數(shù)據(jù)的存儲(chǔ)位置;
    • 僅能夠滿足"=","in",不支持范圍查找(關(guān)鍵)
    • 存在hash沖突
  • B+樹
    • 葉子節(jié)點(diǎn)之間用指針連接,提高了區(qū)間的訪問性能
    • 為什么不用B樹?B+樹設(shè)計(jì)增加每一次的索引數(shù)目,相同的數(shù)據(jù)量下,樹高度小,減少磁盤I/O次數(shù)。

4、最左匹配原則

  • 假設(shè)復(fù)合索引為(A,B,C),底層B+樹是會(huì)按照(A,B,C)的依次排序,如果打破最左匹配原則,跳過了前面的字段后,剩余字段會(huì)是無序的。

5、數(shù)據(jù)庫的ACID屬性

  • A:原子性-事務(wù)所包含的操作要么全部成功執(zhí)行,要么失敗回滾。
  • C:一致性-是指事務(wù)發(fā)生前后數(shù)據(jù)庫要從一個(gè)一致的狀態(tài),變換到另外一個(gè)一致的狀態(tài)。
  • I:隔離性-多個(gè)線程并發(fā)的事務(wù)之間應(yīng)該有一定的隔離措施。
  • D:持久性-事務(wù)的操作一旦提交,將會(huì)對(duì)數(shù)據(jù)庫造成永久的改變。

6、臟讀、不可重復(fù)讀、幻讀

  • 臟讀:是指一個(gè)事務(wù)讀到了另外一個(gè)事務(wù)沒有提交的臟數(shù)據(jù)
  • 不可重復(fù)讀:A線程在事務(wù)中首先讀取一次數(shù)據(jù)n=100,之后B提交了對(duì)n的修改n=150,A線程在同一次事務(wù)中,再讀一次,就讀到n=150。在同一事務(wù)中,兩次讀到的數(shù)據(jù)不一樣;
  • 幻讀:是指A線程的業(yè)務(wù)是首先查詢某一記錄,如果該記錄不存在,則插入記錄。因此,需要執(zhí)行兩條指令。但是,當(dāng)?shù)谝粭l指令執(zhí)行時(shí),同時(shí)又有另外一個(gè)線程在事務(wù)中,插入了新的記錄,且與A線程的插入記錄沖突,對(duì)于A線程來說,就發(fā)生了幻讀。

7、事務(wù)的隔離級(jí)別

  • 讀未提交:在這個(gè)級(jí)別上,所有的事務(wù)都能看見其他線程未提交的記錄;
  • 讀已提交:從一個(gè)事務(wù)開始到提交的過程中,所有的對(duì)記錄的修改都是不可見的,除非該修改提交??梢越鉀Q臟讀的問題,但是不可重復(fù)讀;
  • 可重復(fù)讀:MySQL的默認(rèn)隔離級(jí)別。解決了不可重復(fù)讀的問題,但無法解決臟讀。
  • 串行化:解決所有的事務(wù)問題,但是效率太低。

8、鎖

  • 行鎖:對(duì)某一行的數(shù)據(jù)加鎖
  • 表鎖:對(duì)訪問的整個(gè)表進(jìn)行加鎖
  • 讀鎖:共享鎖
  • 寫鎖:排他鎖
  • 鎖升級(jí):當(dāng)查詢時(shí),如果索引失效,則需要進(jìn)行全表掃描,因此會(huì)對(duì)整個(gè)表進(jìn)行加鎖
  • 間隙鎖:當(dāng)使用范圍查找,并使用共享鎖或者排他鎖時(shí),InnoDB會(huì)給復(fù)合條件的已有記錄進(jìn)行加鎖,同時(shí)還會(huì)對(duì)記錄之間的間隙進(jìn)行加鎖。

9、SQL語句的執(zhí)行順序


10、日志

10.1 錯(cuò)誤日志

  • 默認(rèn)開啟,記錄數(shù)據(jù)庫服務(wù)器在運(yùn)行過程中發(fā)生的嚴(yán)重錯(cuò)誤相關(guān)的信息。

10.2 二進(jìn)制日志

  • BinLog:記錄了所有的DDL(數(shù)據(jù)庫定義語言)和DML(數(shù)據(jù)操縱語言)語句,但是不包括數(shù)據(jù)查詢語句。
  • 該日志對(duì)于災(zāi)難時(shí)的數(shù)據(jù)恢復(fù)起著及其重要的作用
  • 主從復(fù)制也是利用的該日志
  • 默認(rèn)不開啟
  • BinLog日志格式
    • STATEMENT:日志文件中記錄的都是SQL語句。主從復(fù)制時(shí)候,就是拿到這些SQL語句,重新執(zhí)行一次
    • ROW:記錄的是每一行的數(shù)據(jù)變化
    • MIXED:繼承了兩種日志格式

10.3 查詢?nèi)罩?/h4>
  • 記錄了操作數(shù)據(jù)庫相關(guān)的所有操作

10.4 慢查詢?nèi)罩?/h4>
  • 記錄了查詢效率較低的sql語句,可以設(shè)置時(shí)間閾值,默認(rèn)是10s。默認(rèn)不開啟。

11、MVCC

  • 談到MVCC,首先需要說起MySQL的幾個(gè)組件。UndoLog、版本鏈、以及ReadView
  • UndoLog即撤銷日志,目的就是在事務(wù)開始的時(shí)候生成,如果事務(wù)需要回滾,則作為回滾依據(jù);
  • 在MySQL的每一列數(shù)據(jù)中,還維護(hù)著兩個(gè)重要的字段,一個(gè)是修改數(shù)據(jù)的當(dāng)前事務(wù)Id(該事務(wù)并不一定提交),另外一個(gè)是RollBack指針,指向了之前的UndoLog日志,這樣,最終就會(huì)形成如下一條鏈?zhǔn)浇Y(jié)構(gòu),稱為版本鏈。


  • ReadView:這里不討論ReadView具體的可見性算法,只從應(yīng)用上來說。ReadView在進(jìn)行快照讀的時(shí)候產(chǎn)生,其目的是通過自身數(shù)據(jù)結(jié)構(gòu),維護(hù)了當(dāng)前數(shù)據(jù)庫事務(wù)狀態(tài)(涉及到相關(guān)的已經(jīng)提交事務(wù)以及未提交事務(wù))對(duì)當(dāng)前快照讀的可見性。例如,對(duì)于當(dāng)前讀操作,可以屏蔽掉部分未提交事務(wù)。
  • MVCC機(jī)制,實(shí)現(xiàn)了對(duì)于數(shù)據(jù)的當(dāng)前讀操作。
  • RC隔離級(jí)別下,通過快照讀就實(shí)現(xiàn)了對(duì)于未提交數(shù)據(jù)的屏蔽,但是與RR的區(qū)別是,每一次select都會(huì)產(chǎn)生新的read view;
  • RR隔離級(jí)別下,之后在第一次快照讀時(shí)產(chǎn)生新的read view,而后面的繼續(xù)使用該read view。

12、InnoDB和MyISAM

  • InnoDB:支持事務(wù),具有外鍵,回滾和崩潰恢復(fù)能力,線程安全;
  • MyISAM:不支持外鍵和事務(wù),訪問速度快
  • Memony:利用內(nèi)存創(chuàng)建表,訪問速度非???,因?yàn)閿?shù)據(jù)存在于內(nèi)存,而且默認(rèn)使用Hash索引,但是一旦關(guān)閉,數(shù)據(jù)就會(huì)丟失;

12.1 區(qū)別

  • 事務(wù)和外鍵:InnoDB支持事務(wù)和外鍵,強(qiáng)調(diào)安全和完整性,適合大量的DML語句。MyISAM不支持事務(wù)和外鍵,它適合提供高速存儲(chǔ)和檢索。
  • 鎖機(jī)制:
    • InnoDB支持行級(jí)鎖,鎖定的記錄可以鎖定表中的具體記錄?;谒饕齺砑渔i實(shí)現(xiàn)。
    • MyISAM支持表級(jí)鎖,鎖定的是整張表。
  • 索引結(jié)構(gòu)
    • InnoDB使用聚集索引,索引和紀(jì)律在一起記錄,既緩存索引,又緩存記錄;
    • MyISAM使用非聚集索引,索引和記錄分開
  • 并發(fā)處理能力
    • MyISAM使用表鎖,會(huì)導(dǎo)致并發(fā)能力下降,讀之間不阻塞,但是讀寫阻塞;
    • InnoDB讀寫阻塞可以與隔離級(jí)別有關(guān),可以采用多版本并發(fā)控制來支持高并發(fā)
  • 存儲(chǔ)文件
    • InnoDB表對(duì)應(yīng)兩個(gè)文件:一個(gè).frm表結(jié)構(gòu)文件,一個(gè).ibd數(shù)據(jù)文件
    • MyISAM對(duì)應(yīng)三個(gè)文件:一個(gè).frm表結(jié)構(gòu)文件,一個(gè)MYD表數(shù)據(jù)文件,一個(gè).MYI索引文件

13、InnoDB存儲(chǔ)結(jié)構(gòu)

  • 左半部分內(nèi)存結(jié)構(gòu)
    • BufferPool:緩存。以Page為單位,默認(rèn)大小16k,底層采用了鏈表數(shù)據(jù)結(jié)構(gòu)管理
      • Page管理機(jī)制:
        1. free page:空閑頁,未被使用
        2. clean page:被使用的page,數(shù)據(jù)從未被修改過。
        3. dirty page:臟頁,被使用的page,數(shù)據(jù)被修改過,與磁盤中的數(shù)據(jù)不一致
      • 針對(duì)上述三種類型,InnoDB通過三種鏈表結(jié)構(gòu)來進(jìn)行管理和維護(hù)。
      1. free list:表示空閑緩沖區(qū),管理free page
      2. flush list:表示需要刷新到磁盤的緩沖區(qū)域,管理dirty page,內(nèi)部按照page修改時(shí)間排序。臟頁既存在于flush list中也存在于lru list中
      3. lru list:表示正在使用的緩沖區(qū),管理clean page和dirty page,緩沖區(qū)以midpoint為基點(diǎn),劃分出了是否熱點(diǎn)數(shù)據(jù)
      • 改進(jìn)型LRU算法維護(hù)
        • 普通LRU:末尾淘汰法
        • 改進(jìn)型LRU:鏈表劃分為new和old兩個(gè)部分,加入元素時(shí)并不是從表頭插入,而是從中間的midpoint插入,如果數(shù)據(jù)很快再次訪問,那么page就會(huì)像new列表移動(dòng),如果沒有被訪問,則逐步被old部分淘汰
        • 當(dāng)有新的緩存頁加入時(shí),如果有足夠的free page,則從free list拿下使用,如果沒有從lru隊(duì)列中淘汰獲得新頁使用
      • Buffer Pool配置參數(shù)調(diào)優(yōu)
    • ChangeBuffer:緩存DML的數(shù)據(jù),如果DML操作修改的數(shù)據(jù)沒有在內(nèi)存(即在BufferPool中沒有命中)中,那么InnoDB不著急將修改頁調(diào)入內(nèi)存,而是先記錄在緩沖池中,等到①該頁面被調(diào)入內(nèi)存;②服務(wù)器空閑;③服務(wù)器shutdown時(shí),寫回。
      • 當(dāng)下次查詢記錄時(shí),首先從磁盤中讀取,然后將讀取到的信息與ChangeBuffer中的信息合并,最終載入到BufferPool
      • 寫緩沖區(qū)僅適用于非唯一的普通索引頁。如果在索引中設(shè)置了唯一性,在進(jìn)行修改時(shí),INnoDB必須要進(jìn)行唯一性校驗(yàn),因此該情況下寫緩存失效。
    • Log Buffer:redo、undo
    • 自適應(yīng)哈希索引:對(duì)Buffer Pool進(jìn)行優(yōu)化
  • 右半部分磁盤結(jié)構(gòu)
    • 系統(tǒng)表空間
    • 獨(dú)立表空間
    • 通用表空間
    • Undo表空間
    • Redo Log

14、InnoDB數(shù)據(jù)文件

  • Innodb數(shù)據(jù)文件存儲(chǔ)結(jié)構(gòu),分為一個(gè)ibd數(shù)據(jù)文件->Segment(段)->Extent(區(qū))->Page(頁)->Row(行)
    • Tablespace:表空間,用于存儲(chǔ)多個(gè)ibd數(shù)據(jù)文件,用于存儲(chǔ)表的記錄和索引。一個(gè)文件包含多個(gè)段
    • Segment:段,用于管理多個(gè)Extent,分為數(shù)據(jù)段(Leaf node segment)、索引段(Non-leaf node segment)、回滾段(rollback segment)。一個(gè)表至少會(huì)有兩個(gè)segment,一個(gè)管理數(shù)據(jù),一個(gè)管理索引。每創(chuàng)建一個(gè)索引,會(huì)多兩個(gè)段
    • Extent:區(qū),一個(gè)區(qū)固定包含64個(gè)連續(xù)頁,大小為1M。當(dāng)表空間不足時(shí),需要重新分配頁資源,會(huì)直接創(chuàng)建一個(gè)區(qū)。
    • Page:頁,用于存儲(chǔ)多行Row數(shù)據(jù),大小為16K。包含很多種頁類型,undo頁,系統(tǒng)頁,事務(wù)數(shù)據(jù)頁,大的BLOB對(duì)象頁。
    • Row:行,包含了記錄的字段值,事務(wù)ID,滾動(dòng)指針,字段指針等信息
  • page是文件最基本的單位,無論何種類型的page,都是由page header,page tailer和page body組成。


15、Undo Log

15.1 Undo Log介紹

  • 以撤銷和取消為目的的日志,返回某個(gè)指定的狀態(tài)。在事務(wù)開始之前,會(huì)將過程中修改的記錄保存到Undo日志中,當(dāng)事務(wù)回滾或者數(shù)據(jù)庫崩潰時(shí),可以利用Undo日志,撤銷未提交的事務(wù)對(duì)數(shù)據(jù)庫產(chǎn)生的影響;
  • Undo日志在數(shù)據(jù)庫事務(wù)開始的時(shí)候被創(chuàng)建;事務(wù)提交后,Undo日志并不會(huì)立即刪除,而是會(huì)放到undo Log列表中,等待后臺(tái)線程的刪除。

15.2 Undo Log的作用

  • 實(shí)現(xiàn)事務(wù)的原子性
  • MVCC

16、Redo Log

  • RedoLog顧名思義就是重做日志,以恢復(fù)數(shù)據(jù)為目的。
  • 隨著事務(wù)操作的執(zhí)行,會(huì)生成RedoLog,在事務(wù)提交時(shí),將產(chǎn)生的RedoLog寫入到LogBuffer中,并不是隨著事務(wù)的提交立即刷入磁盤。
  • 當(dāng)相關(guān)的事務(wù)被持久化到磁盤之后,RedoLog的使命即完成,其空間可以被重用,相應(yīng)的可以被覆蓋。
  • Redo可以被看做是一種低成本的臨時(shí)持久化方案。雖然相同的數(shù)據(jù)也被持久化到了最終的數(shù)據(jù)文件中,但是,相對(duì)于這個(gè)過程,Redo時(shí)低成本的,不涉及索引、調(diào)整等操作,只是做臨時(shí)的數(shù)據(jù)備份。
  • 其有三種工作模式:0-每秒提交一次RedoBuffer到OS Cache,并將OS Cache中數(shù)據(jù)刷入磁盤;1-隨著事務(wù)的提交,立即提交到OS Cache,并立即刷入磁盤。這種方式,安全但是性能差;2-立即提交到OS Cache,但是后臺(tái)每秒刷一次盤。

17、Undo Log和Redo Log對(duì)比總結(jié)

  • UndoLog-以撤銷為目的的日志,返回到某個(gè)執(zhí)行的狀態(tài);RedoLog-重做日志,以數(shù)據(jù)恢復(fù)為目的;
  • UndoLog-是對(duì)于數(shù)據(jù)庫狀態(tài)邏輯上的回滾,其會(huì)記錄一個(gè)相反的操作,而是數(shù)據(jù)庫從邏輯上恢復(fù)到之前狀態(tài)。RedoLog:物理格式日志,記錄的是物理數(shù)據(jù)頁面的修改信息。
  • UndoLog-當(dāng)事務(wù)提交后,并不立即清除,會(huì)有一個(gè)purge線程判斷是否會(huì)在其他事務(wù)的管理版本中使用;RedoLog- 當(dāng)臟頁數(shù)據(jù)寫到磁盤后,開始清除。

18、DoubleWrite

  • DoubleWrite保證了InnoDB存儲(chǔ)頁的可靠性。在對(duì)緩沖池中的臟頁進(jìn)行刷新時(shí),并不是寫入磁盤。而是首先將其寫入到DoubleWrite中,DW分為內(nèi)存和磁盤兩部分,存儲(chǔ)引擎首先將臟頁拷貝到內(nèi)存中的buffer中,之后再寫入并刷盤至磁盤。

19、DML語句

  • Modify
update 表名
set 列名=新值
where 條件
  • detele
delete 
from 表名
where 條件
  • insert
insert into
表名(列名) 
新值()
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1. MySQL體系架構(gòu) MySQL Server架構(gòu)自頂向下大致可以分 、 、 和 。 1.1 網(wǎng)絡(luò)連接層 客戶...
    干天慈雨閱讀 592評(píng)論 0 1
  • MySQL技術(shù)內(nèi)幕:InnoDB存儲(chǔ)引擎(第2版) 姜承堯 第1章 MySQL體系結(jié)構(gòu)和存儲(chǔ)引擎 >> 在上述例子...
    沉默劍士閱讀 7,647評(píng)論 0 16
  • Mysql概述 數(shù)據(jù)庫是一個(gè)易于訪問和修改的信息集合。它允許使用事務(wù)來確保數(shù)據(jù)的安全性和一致性,并能快速處理百萬條...
    彥幀閱讀 13,966評(píng)論 10 460
  • 1 事務(wù)介紹 在MySQL中的事務(wù)是由存儲(chǔ)引擎實(shí)現(xiàn)的,而且支持事務(wù)的存儲(chǔ)引擎不多,我們主要講解InnoDB存儲(chǔ)引...
    MiniSoulBigBang閱讀 843評(píng)論 0 3
  • 前言 ??本文是對(duì)《java拉勾高薪訓(xùn)練營》中的mysql架構(gòu)原理進(jìn)行復(fù)習(xí),文中所有內(nèi)容均來自于mysql課件,非...
    體驗(yàn)人生認(rèn)真生活閱讀 729評(píng)論 1 3

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