title: Mysql復習總結
categories:
- 秋招面試
tags: - 面試
- mysql
<Excerpt in index | 首頁摘要>
別問 問就是為了面試豁出了老命
<The rest of contents | 余下全文>
數據庫特性
- 原子性
- 一致性
- 隔離性
- 持久性
原子性
所謂原子性就是事務的執行,要么全部成功,要么全部失敗。
一致性
事務操作的完整性約束不會破壞,是原子性的一種表現,例如A向B轉賬,不會發生A金額發生變化,但是B金額不會發生變化的情況
隔離性
事務之間的操作是互相隔離的,且不受彼此的影響
持久性
事務完成后,所有數據保存在數據庫中,持久存在,且不能回滾。
Mysql事務所存在的問題
- 臟讀 (Select沒有規矩)
事務A插入了一條數據,但是還沒有提交,結果事務B去讀取數據表,發現了數據A要插入的數據,就是臟讀
- 不可重復讀 (Update沒有規矩)
事務A首次讀某條數據為a,但是事務b此時更新了該條數據為b,結果A再次讀取這條數據的時候就變成了b,就是不可重復讀
- 幻讀 (insert,delete沒有規矩)
事務A讀取了數據表,事務B又插入了幾條數據,當事務A再次讀取數據表的時候,發現數據多了幾條,就是幻讀
數據庫隔離級別
- 未提交讀
事務之間可以讀取到事務未提交的數據 (完美的符合了上面出現的所有問題)
- 提交讀
事務必須提交之后,提交的數據才可以被其它的事務所看到。
- 可重復讀
悲觀鎖讀,若一個事務A讀取該條數據,那么不管其它的事務如何去更改這條數據,那么事務A依然讀取到的是第一次讀取到的數據。
- 串行化
事務操作一個一個按照順序來,慢是最大的問題
Mysql中的log
- bin log
記錄數據庫的變更操作,例如delete,insert,update等操作,不會記錄select,用于數據的恢復和復制,
記錄形式為 一些sql語句還有一些事務id等內容
- redo log
[圖片上傳失敗...(image-1255ac-1594521199607)]
數據的讀取或者說是修改操作,是先找到頁,再讀到內存,如果發生修改,讀到內存后,還沒來得及刷到磁盤,數據庫gg了,那么數據容易丟失,但是redo log會記錄頁的變更內容,那么恢復數據庫的話,就不會丟失數據了。
- undo log
和redo log相反,在讀到內存的時候,undo log還會記錄相反的內容,比如redo是insert那么undo就是要記錄delete的操作,記錄的和binlog一樣,屬于邏輯變化
bin log VS redo log
- binlog記錄的是sql的語句等內容,redolog記錄的則是XX頁在XX行改了XX數據
- binlog存在于所有的數據庫系統,redo則是innodb的獨家內容
- redolog 和 binlog 必須數據都一致才算是正常,要不然都會回滾
MVCC
多版本并發控制,其實就是為每一條數據都填設一個版本號,因此提交讀和重復讀所讀取的數據都是其中的快照讀的一種
ACID如何被保證的
- 原子性如何保證
如果事務失敗則使用undolog進行會滾
- 隔離性如何保證
MVCC,即多版本并發控制(Multi Version Concurrency Control),一個行記錄數據有多個版本對快照數據。 => 也就是快照讀
- 持久性如何保證
redolog用于保證其持久性
存儲引擎 (Innodb 和 MyISAM)
- InnoDB支持事務,但是MyISAM不支持事務
- InnoDB支持外鍵,但是MyISAM不支持外鍵
- InnoDB是行級鎖,但是MyISAM是表級鎖
- InnoDB是聚集索引(數據文件和索引是綁定的,也就是說,先查到索引,之后才可以查到數據),但是MyISAM是非聚集索引(也就是說數據和索引是相互分開的,索引直接鏈接著數據的地址)
(換句話說:InnoDB下,索引就真的是索引,輔助索引則是數據的指針;但是MyISAM的主索引和輔助索引則都是數據指針) - InnoDB不支持全文搜索,但是MyISAM則支持全文搜索 (!mysql5.7之后innoDB也是可以支持全文搜索的)
- 面試考的比較少了,但是可以看看
- InnoDB不保存表的具體行數,執行select count(*) from table時需要全表掃描,而MyISAM用一個變量保存了整個表的行數,執行上述語句時只需要讀出該變量即可
- MyISAM表格可以被壓縮后進行查詢操作
InnoDB的自適應hash算法((Adaptive Hash Index, AHI))
InnoDB存儲引擎會自動根據訪問的頻率和模式來自動地為某些熱點頁建立哈希索引
InnoDB存儲引擎會監控對表上各索引頁的查詢。如果觀察到建立哈希索引可以帶來速度提升,則建立哈希索引
InnoDB為什么推薦使用自增ID作為主鍵?
自增ID可以保證每次插入時B+索引是從右邊擴展的,可以避免B+樹和頻繁合并和分裂(對比使用UUID)。如果使用字符串主鍵和隨機主鍵,會使得數據隨機插入,效率比較差。
數據結構 - 查找樹,紅黑樹,b樹和b+樹
查找樹是不平衡的,舉個例子來說,如果是插入(1,2,3,4,5),那么數據查找在查找樹中會全部在一邊,構成一個鏈表
紅黑樹是平衡的,但是紅黑樹是一顆二叉樹,深度問題還是沒有解決
b樹在一定程度上其實已經解決了前兩個的問題,簡單的說就是:多叉的平衡樹;但是b+樹需要指定葉子節點的最大值,因此是無法也不能更好的始應數據庫的需求
b+樹是b樹的升級版,b+樹的非葉子節點只存儲數據索引,且從左向右也是從小到大的排列,這樣就可以更多的讓索引存儲,之后在葉子節點才是真正的數據部分,且每個葉子節點的最后會是指針指向旁邊的葉子節點
image
索引
索引類型
- 普通索引
就是最基本的添加一個索引,用于加速查找
- 唯一索引
列值必須唯一,可以為空值,加速查找
- 主鍵索引
利用主鍵作為索引,而且不可以為空,加速查找
- 覆蓋索引
就是查查找的數據也是索引值
- 組合索引
幾列合并成一個索引,但是遵循最左原則
- 全文索引
全文分詞查找,innoDB是做不到的,需要第三方,比如es等
索引帶來的問題
使用索引的時候不可以隨便使用,過度的使用索引會導致消耗大量的資源,熱點核心業務的數據應該多使用索引
索引會浪費磁盤空間,不要創建非必要的索引,插入、更新、刪除需要維護索引,帶來額外的開銷,索引過多,修改表的時候重構索引性能差
但是索引使用的時候可以減少查詢次數,提高效率
查詢的順序
- from 從哪個表查詢
- where 初步過濾條件
- group by 過濾后進行分組[重點]
- having 對分組后的數據進行二次過濾[重點]
- select 查看哪些結果字段
- order by 按照怎樣的順序進行排序返回[重點]
數據庫設計三范式
- 1NF : 原子性 字段不可再分,否則就不是關系數據庫
- 2NF : 唯一性 每一個主鍵是唯一的
- 3NF : 要求一個數據庫表中不包含已在其他表中已包含的非主關鍵字信息, 例如 存在一個課程表,課程表中有課程號(Cno),課程名(Cname),學分(Ccredit),那么在學生信息表中就沒必要再把課程名,學分再存儲到學生表中,這樣會造成數據的冗余