前言
本文主要閱聽人為開發人員,是以不涉及到MySQL的服務部署等操作,且内容較多,大家準備好耐心和瓜子礦泉水.
前一陣系統的學習了一下MySQL,也有一些實際操作經驗,偶然看到一篇和MySQL相關的面試文章,發現其中的一些問題自己也回答不好,雖然知識點大部分都知道,但是無法将知識串聯起來.
是以決定搞一個MySQL靈魂100問,試着用回答問題的方式,讓自己對知識點的了解更加深入一點.
此文不會事無巨細的從select的用法開始講解mysql,主要針對的是開發人員需要知道的一些MySQL的知識點,主要包括索引,事務,優化等方面,以在面試中高頻的問句形式給出答案.
索引相關
關于MySQL的索引,曾經進行過一次總結,文章連結在這裡 Mysql索引原理及其優化.
1. 什麼是索引?
索引是一種資料結構,可以幫助我們快速的進行資料的查找.
2. 索引是個什麼樣的資料結構呢?
索引的資料結構和具體存儲引擎的實作有關, 在MySQL中使用較多的索引有Hash索引,B+樹索引等,而我們經常使用的InnoDB存儲引擎的預設索引實作為:B+樹索引.
3. Hash索引和B+樹所有有什麼差別或者說優劣呢?
首先要知道Hash索引和B+樹索引的底層實作原理:
hash索引底層就是hash表,進行查找時,調用一次hash函數就可以擷取到相應的鍵值,之後進行回表查詢獲得實際資料.B+樹底層實作是多路平衡查找樹.對于每一次的查詢都是從根節點出發,查找到葉子節點方可以獲得所查鍵值,然後根據查詢判斷是否需要回表查詢資料.
那麼可以看出他們有以下的不同:
- hash索引進行等值查詢更快(一般情況下),但是卻無法進行範圍查詢.
因為在hash索引中經過hash函數建立索引之後,索引的順序與原順序無法保持一緻,不能支援範圍查詢.而B+樹的的所有節點皆遵循(左節點小于父節點,右節點大于父節點,多叉樹也類似),天然支援範圍.
- hash索引不支援使用索引進行排序,原理同上.
- hash索引不支援模糊查詢以及多列索引的最左字首比對.原理也是因為hash函數的不可預測.AAAA和AAAAB的索引沒有相關性.
- hash索引任何時候都避免不了回表查詢資料,而B+樹在符合某些條件(聚簇索引,覆寫索引等)的時候可以隻通過索引完成查詢.
- hash索引雖然在等值查詢上較快,但是不穩定.性能不可預測,當某個鍵值存在大量重複的時候,發生hash碰撞,此時效率可能極差.而B+樹的查詢效率比較穩定,對于所有的查詢都是從根節點到葉子節點,且樹的高度較低.
是以,在大多數情況下,直接選擇B+樹索引可以獲得穩定且較好的查詢速度.而不需要使用hash索引.
4. 上面提到了B+樹在滿足聚簇索引和覆寫索引的時候不需要回表查詢資料,什麼是聚簇索引?
5. 非聚簇索引一定會回表查詢嗎?
6. 在建立索引的時候,都有哪些需要考慮的因素呢?
7. 聯合索引是什麼?為什麼需要注意聯合索引中的順序?
8. 建立的索引有沒有被使用到?或者說怎麼才可以知道這條語句運作很慢的原因?
9. 那麼在哪些情況下會發生針對該列建立了索引但是在查詢的時候并沒有使用呢?
事務相關
1. 什麼是事務?
了解什麼是事務最經典的就是轉賬的栗子,相信大家也都了解,這裡就不再說一邊了.
事務是一系列的操作,他們要符合ACID特性.最常見的了解就是:事務中的操作要麼全部成功,要麼全部失敗.但是隻是這樣還不夠的.
2. ACID是什麼?可以詳細說一下嗎?
A=Atomicity
原子性,就是上面說的,要麼全部成功,要麼全部失敗.不可能隻執行一部分操作.
C=Consistency
系統(資料庫)總是從一個一緻性的狀态轉移到另一個一緻性的狀态,不會存在中間狀态.
I=Isolation
隔離性: 通常來說:一個事務在完全送出之前,對其他事務是不可見的.注意前面的通常來說加了紅色,意味着有例外情況.
D=Durability
持久性,一旦事務送出,那麼就永遠是這樣子了,哪怕系統崩潰也不會影響到這個事務的結果.
3. 同時有多個事務在進行會怎麼樣呢?
多事務的并發進行一般會造成以下幾個問題:
- 髒讀: A事務讀取到了B事務未送出的内容,而B事務後面進行了復原.
- 不可重複讀: 當設定A事務隻能讀取B事務已經送出的部分,會造成在A事務内的兩次查詢,結果竟然不一樣,因為在此期間B事務進行了送出操作.
- 幻讀: A事務讀取了一個範圍的内容,而同時B事務在此期間插入了一條資料.造成"幻覺".
4. 怎麼解決這些問題呢?MySQL的事務隔離級别了解嗎?
5. Innodb使用的是哪種隔離級别呢?
6. 對MySQL的鎖了解嗎?
7. MySQL都有哪些鎖呢?像上面那樣子進行鎖定豈不是有點阻礙并發效率了?
表結構設計
1. 為什麼要盡量設定一個主鍵?
2. 主鍵使用自增ID還是UUID?
3. 字段為什麼要求定義為not null?
4. 如果要存儲使用者的密碼散列,應該使用什麼字段進行存儲?
密碼散列,鹽,使用者身份證号等固定長度的字元串應該使用char而不是varchar來存儲,這樣可以節省空間且提高檢索效率.
存儲引擎相關
1. MySQL支援哪些存儲引擎?
MySQL支援多種存儲引擎,比如InnoDB,MyISAM,Memory,Archive等等.在大多數的情況下,直接選擇使用InnoDB引擎都是最合适的,InnoDB也是MySQL的預設存儲引擎.
InnoDB和MyISAM有什麼差別?
- InnoDB支援事物,而MyISAM不支援事物
- InnoDB支援行級鎖,而MyISAM支援表級鎖
- InnoDB支援MVCC, 而MyISAM不支援
- InnoDB支援外鍵,而MyISAM不支援
- InnoDB不支援全文索引,而MyISAM支援。
零散問題
1. MySQL中的varchar和char有什麼差別.
2. varchar(10)和int(10)代表什麼含義?
3. MySQL的binlog有有幾種錄入格式?分别有什麼差別?
4. 超大分頁怎麼處理?
5. 關心過業務系統裡面的sql耗時嗎?統計過慢查詢嗎?對慢查詢都怎麼優化過?
6. 上面提到橫向分表和縱向分表,可以分别舉一個适合他們的例子嗎?
7. 什麼是存儲過程?有哪些優缺點?
8. 說一說三個範式
9. MyBatis中的#