面試_mysql
- 1. 基礎知識
-
- 1) 資料庫三大範式是什麼
- 2) mysql有關權限的表
- 3) binlog錄入格式
- 4) char、varchar 差別
- 5)int(20)中20的涵義
- 6) 字段為什麼要求定義為not null?
- 7) 雪花算法原理?為什麼是順序ID? 如何解決時鐘回撥?
- 8) 自增ID與UUID的差別
- 9) 為何用自增主鍵(自增ID的好處)?
- 10) 什麼是臨時表,臨時表什麼時候删除?
- 11) UNION、UNION ALL差別
- 12) SQL語句分類
- 14) in、exists 差別
- 2. 存儲引擎
-
- 1) InnoDB、MyIsam、Memmry的差別
- 2) MyISAM索引、InnoDB索引的差別
- 3) 存儲引擎選擇
- 4) [InnoDB引擎的4大特性](https://zhuanlan.zhihu.com/p/109528131)
- 5) InnoDB如何存資料的
- 6) InnoDB索引類型,差別?
- 3. 索引
-
- 1) 什麼是索引?
- 2) 索引使用場景(重點)
- 3) 索引代價
- 4) 索引分類
- 5) 少建索引的原則
- 6)建立索引的原則(重中之重)
- 7) 索引建立、删除
- 8) 聚簇、非聚簇差別
- 9) 适合使用索引覆寫來優化SQL的場景
- 10) B+樹索引、 Hash索引差別
- 11) B+樹索引、B樹索引差別?為什麼使用B+樹而不是B樹?
- 12) 如何利用索引提升查詢性能?
- 13) 索引維護
- 4. 事務
-
- 1) 什麼是資料庫事務?
- 2) 事物的四大特性(ACID)
- 3) [ACID實作原理](https://www.cnblogs.com/kismetv/p/10331633.html)
- 4) 事務的隔離級别
- 5) [四個隔離級别的實作原理](https://blog.csdn.net/QEcode/article/details/97274409)
- 5. 鎖
-
- 1) InnoDB鎖的算法
- 2) 鎖類别
- 3) 死鎖判定原理和具體場景,死鎖怎麼解決?
- 4) InnoDB行鎖的實作
- 6. MySQL高并發
-
- 1) 高并發解決方案
- 2) 分表後的ID怎麼保證唯一性?
- 3) mysql主從同步怎麼做?
1. 基礎知識
1) 資料庫三大範式是什麼
範式 | 規則 |
---|---|
1NF | 列不可以拆分。 |
2NF | 1NF + 非主鍵列完全依賴于主鍵(非一部分) |
3NF | 2NF + 非主鍵列隻依賴于主鍵 |
2) mysql有關權限的表
表名 | 内容 |
---|---|
user | 記錄允許連接配接到伺服器的使用者帳号資訊,裡面的權限是全局級的 |
db | 記錄各個帳号在各個資料庫上的操作權限 |
table_priv | 記錄資料表級的操作權限 |
columns_priv | 記錄資料列級的操作權限 |
host | 配合db權限表對給定主機上資料庫級操作權限作更細緻的控制。 這個權限表不受GRANT和REVOKE語句的影響 |
3) binlog錄入格式
格式 | 内容 |
---|---|
statement | 每一條會修改資料的sql都會記錄在binlog中 |
row | 不記錄 sql 語句上下文相關資訊,僅儲存哪條記錄被修改 |
mixed | 普通操作使用statement記錄,當無法使用statement的時候使用row。 |
4) char、varchar 差別
char | varchar |
---|---|
定長 | 長可變 |
存取速度快,便于存儲查找 | 慢 |
最多存 255,非unicode | 最多存 65532,非unicode |
英文1位元組,中文2位元組 | 均為2位元組 |
長度 < 定長,空格填充 | 按插入資料的長度來存儲 |
5)int(20)中20的涵義
- 顯示字元的長度。
- 20表示最大顯示寬度為20,但仍占4位元組存儲,存儲範圍不變;
- 不影響内部存儲,隻是影響帶
定義的 int 時,前面補多少個 0,易于報表展示zerofill
6) 字段為什麼要求定義為not null?
null
值會占用更多的位元組。
7) 雪花算法原理?為什麼是順序ID? 如何解決時鐘回撥?
-
1bit無用符号位 + 41bit時間戳 + 10bit機器ID + 12bit序列号
- 時間戳在高位,整個ID都是趨勢遞增的。
- 時鐘回撥問題的解決方案讨論
- 時間戳自增(徹底解決)
- 緩存曆史序列号(緩解)
- 等待時鐘校正
8) 自增ID與UUID的差別
- UUID隻是
,在高并發情況下不會出現ID沖突全球唯一Id
- 自增ID
- 字段長度較uuid小很多,
占空間小
- 增量增長,按順序存放,對于檢索非常有利,作為聚簇索引
。提升查詢效率
- 字段長度較uuid小很多,
9) 為何用自增主鍵(自增ID的好處)?
- InnoDB使用主鍵索引,用自增主鍵,每次插入記錄會
到目前索引節點的後續位置順序添加
- 不是自增主鍵,可能會在中間插入引起B+樹的
節點分裂
10) 什麼是臨時表,臨時表什麼時候删除?
- 存儲一些中間結果集的表
- 臨時表隻在目前連接配接可見
- 當關閉連接配接時,Mysql會自動删除表并釋放所有空間。
- 記憶體臨時表(
)memory
- 磁盤臨時表(5.7.6後
,之前innodb
)myisam
- 記憶體臨時表(
11) UNION、UNION ALL差別
-
不會合并重複的記錄行UNION ALL
-
效率 高于UNION
UNION ALL
12) SQL語句分類
- 資料定義語言DDL:
CREATE,DROP,ALTER
- 資料查詢語言DQL:
SELECT
- 資料操縱語言DML:
INSERT,UPDATE,DELETE
- 資料控制功能DCL:
GRANT,REVOKE,COMMIT,ROLLBACK
14) in、exists 差別
- in:外表和内表作
連接配接hash
- exists :對外表作
循環,每次loop
循環再對内表進行查詢。loop
2. 存儲引擎
1) InnoDB、MyIsam、Memmry的差別
種類 | InnoDB | MyISAM | Memmry |
---|---|---|---|
鎖機制 | 行鎖、表鎖 | 表鎖 | 表鎖 |
B+樹索引 | 支援( ) | 支援 ( ) | 支援 |
哈希索引 | X | X | 支援 |
全文索引 | 5.6後支援 | 支援 | X |
外鍵 | 支援 | X | X |
事務 | 支援 | X | X |
記錄存儲順序 | 按插入順序儲存 | 主鍵大小有序插入 |
2) MyISAM索引、InnoDB索引的差別
InnoDB索引 | MyISAM索引 |
---|---|
| |
索引的葉子節點存儲着 索引的葉子節點存儲的是 | 葉子節點存儲的是 需要 一次才能得到資料 |
3) 存儲引擎選擇
- 預設的
Innodb
- 更新(删除)頻率高
- 資料的完整性
- 并發量高,支援事務和外鍵
- 崩潰後更容易恢複
-
MyISAM
- 讀寫插入為主的應用
- 全文搜尋
- 高速存儲、檢索
4) InnoDB引擎的4大特性
- 插入緩沖(insert buffer)
- 二次寫(double write)
- 自适應哈希索引(ahi)
- 預讀(read ahead)
5) InnoDB如何存資料的
- 5.6 之前 系統表空間 , 對應
檔案ibdata1
- 5.6 之後 獨立表空間
- 8.0 之前
-
檔案裡儲存的僅僅是該表的資料ibd
-
檔案裡儲存表結構frm
-
- 8.0 之後, 表結構資訊以
的形式放在了SDI
檔案中ibd
- 8.0 之前
6) InnoDB索引類型,差別?
主鍵索引 | 非主鍵索引 |
---|---|
聚簇 | 輔助 |
ID主鍵即可查詢出資料行 | 可能需要回表 |
3. 索引
1) 什麼是索引?
- 一種特殊的
檔案
- 一種用于快速查找資料的
資料結構
2) 索引使用場景(重點)
- where
- order by
- join
3) 索引代價
- 占用磁盤空間
- 建立或修改等操作時,比沒有索引或沒有建立覆寫索引時的要慢。
- 索引是有大量資料的時候才建立的,沒有大量資料反而會浪費時間。
4) 索引分類
分類标準 | 分類 |
---|---|
資料結構 | B+Tree 、 Hash索引 、 全文索引 |
實體存儲 | 聚簇索引 、 非聚簇索引(二級、輔助) |
字段特性 | 普通索引 唯一索引 (值唯一,允許有空值)、主鍵索引 (不允許有空值) 字首索引(選擇索引列的最左n個字元來建立索引) |
字段個數 | 單列索引、 聯合索引 |
5) 少建索引的原則
- 表記錄太少
- 經常插入、删除、修改的表
- 資料重複且分布平均的表字段。(字段A隻有T和F兩種值,且每個值的分布機率大約為50%)
- 經常和主字段一塊查詢但主字段索引值比較多的表字段
6)建立索引的原則(重中之重)
- 最左字首比對原則
- 查詢頻繁的字段
- 有外鍵的資料列
- 字段唯一
- 查詢中排序的字段
- 查詢中統計或分組統計的字段
7) 索引建立、删除
-
時建立CREATE TABLE
-
添加ALTER TABLE
-
指令建立CREATE INDEX
- 删除普通索引、唯一索引、全文索引:
alter table 表名 drop KEY 索引名
- 删除主鍵索引:
alter table 表名 drop primary key
8) 聚簇、非聚簇差別
聚簇索引 | 非聚簇索引 |
---|---|
順序存儲 | 無序存儲 |
葉子節點 | 葉子節點 (InnoDB) 指向存放資料塊的 (MyISAM) |
| 多個 |
,資料頁上一級索引存儲是 | ,資料頁上一級索引頁為 |
9) 适合使用索引覆寫來優化SQL的場景
- 全表count查詢優化
- 列查詢回表優化
- 分頁查詢
10) B+樹索引、 Hash索引差別
Hash索引相比B+樹索引的優缺點
- 不支援
範圍查詢
- 不支援
模糊查詢
- 不支援
聯合索引的最左比對規則
- 不支援
利用索引完成排序
- 存在
問題哈希碰撞
- 避免不了
查詢資料回表
-
效果更好,但是不穩定等值查詢
11) B+樹索引、B樹索引差別?為什麼使用B+樹而不是B樹?
特點 | BTree | B+Tree |
---|---|---|
結點 | 索引 + 資料 | ,且葉子結點間存在 |
随機檢索 | 支援 | 支援 |
| X | 支援 |
| X | 支援 |
查詢效率 | 更穩定 | |
元素周遊 | 效率低下 | |
增删檔案(節點)的效率 | 更高 | |
空間使用率更高, | X | 支援 |
12) 如何利用索引提升查詢性能?
-
:減少回表次數覆寫索引
- 聯合索引的
最左字首原則
-
:節省了一次回表次數索引下推
用
聯合索引
時
先通過前一個字段的索引找到合适位置之後
sql引擎會
自動判斷後一個字段
的值是否符合條件,
如果符合條件的話,
取出主鍵ID進行回表查詢
13) 索引維護
- 直接優化表 順帶會優化索引
- 删除索引,從新建立
- 修改索引
ALTER INDEX 索引名 REBUILD ; ALTER INDEX 索引名 REBUILD ONLINE; ALTER INDEX 索引名 REBUILD ONLINE NOLOGGING;
- 合并索引:不需額外存儲空間,代價較低
4. 事務
1) 什麼是資料庫事務?
- 事務是一個
。不可分割的資料庫操作序列
- 事務是資料庫并發控制的基本機關,其執行的結果必須使資料庫從
變到一種一緻性狀态
。另一種一緻性狀态
- 事務是邏輯上的一組操作,
。要麼都執行,要麼都不執行
2) 事物的四大特性(ACID)
-
: 事務是最小的執行機關,不允許分割。要麼都執行,要麼都不執行。原子性
-
: 執行事務前後,資料保持一緻,多個事務對同一個資料讀取的結果是相同的;一緻性
-
: 并發通路資料庫時,一個使用者的事務不被其他事務所幹擾,各并發事務之間資料庫是獨立的;隔離性
-
: 一個事務被送出之後。它對資料庫中資料的改變是持久的,即使資料庫發生故障也不應該對其有任何影響持久性
3) ACID實作原理
- 原子性:
,事務修改資料庫時記錄,失敗復原undo log
- 一緻性:
其餘三大特性 + 應用層代碼控制
- 隔離性:
鎖 + MVCC(隐藏列、基于undo log的版本鍊、ReadView)
- 持久性:
,資料修改時記錄,事務送出時刷盤,當機則可讀取redo log中的資料來恢複redo log
4) 事務的隔離級别
事務隔離級别 | 讀未送出 | 讀已送出 | 可重複讀 | 串行化 | 備注 |
---|---|---|---|---|---|
髒讀 | √ | X | X | X | |
不可重複讀 | √ | √ | X | X | |
幻讀 | √ | √ | √ | X | |
5) 四個隔離級别的實作原理
操作 | 讀未送出 | 讀已送出 | 可重複讀 | 串行化 |
---|---|---|---|---|
讀 | 不加鎖 | 不加鎖, ReadView | 不加鎖, ReadView | 加鎖 |
寫 | 行鎖(排它鎖) | 行鎖, undo log的版本鍊 | 行鎖, undo log的版本鍊 | 加鎖 |
RC 和 RR 不同之處:行記錄對于目前事務的
可見性
- RC級别對資料的可見性是該資料的
,最新記錄
- RR基本對資料的可見性是
。事務開始時,該資料的記錄
5. 鎖
1) InnoDB鎖的算法
- Record lock:
行鎖
- Gap lock:
,鎖定一個範圍,不包括記錄本身間隙鎖
-
:record + gap 鎖定一個範圍,包含記錄本身Next-key lock
2) 鎖類别
- 樂觀鎖:
、版本号控制
CAS算法原理
- 悲觀鎖:
鎖
-
(讀鎖):共享鎖
in share mode
-
(寫鎖):排他鎖
for update
-
3) 死鎖判定原理和具體場景,死鎖怎麼解決?
- 死鎖判定原理
- 互斥條件:一個資源每次隻能被一個程序使用。
- 請求與保持條件:一個程序因請求資源而阻塞時,對已獲得的資源保持不放。
- 不剝奪條件:程序已獲得的資源,在末使用完之前,不能強行剝奪。
- 循環等待條件:若幹程序之間形成一種頭尾相接的循環等待資源關系。
- 有助于最大限度地降低死鎖
- 順序通路。
- 一次請求所有資源
- 主動釋放鎖
- mysql中避免死鎖:避免事務中的使用者互動。保持事務簡短并在一個批進行中。使用低隔離級别。使用綁定連接配接。
- MySQL解決死鎖方法
- 第一種: 查詢是否鎖表 -->查詢程序 --> 殺死程序id
kill id
- 第二種: 檢視目前的事務 --> 檢視目前鎖定的事務 --> 檢視目前等鎖的事務 --> 殺死程序id
- 第一種: 查詢是否鎖表 -->查詢程序 --> 殺死程序id
4) InnoDB行鎖的實作
基于索引,
for update
6. MySQL高并發
1) 高并發解決方案
-
,由單點分布到多點資料庫中,進而降低單點資料庫壓力。水準分庫分表
- ** 叢集**方案:解決DB當機帶來的單點DB不能通路問題。
- 引入
政策(LoadBalancePolicy簡稱LB)負載均衡
-
實作讀寫主從複制
:極大限度提高了應用中Read資料的速度和并發量。無法解決高寫入壓力分離政策
- 通過
攔截sql語句,僅mybatis plugin
通路salve庫select
-
通過plugin
或者注解
來標明分析語句是讀寫方法
主從庫
- 重寫一下
來支援事務, 将DataSourceTransactionManager
的事務扔進讀庫, 其餘扔進寫庫。read-only
- 通過
- 使用
,讓請求先通路到redisredis做一個緩沖操作
-
政策延時雙删
-
(基于訂閱異步更新緩存
的同步機制)binlog
-
2) 分表後的ID怎麼保證唯一性?
-
設定步長
-
,如雪花算法分布式ID
-
每張表單獨新增一個字段作為唯一主鍵
3) mysql主從同步怎麼做?
-
的原理(異步)主從同步
- master送出完事務後,寫入binlog
- slave連接配接到master,擷取binlog
- master建立dump線程,推送binlog到slave
- slave啟動一個IO線程讀取同步過來的master的binlog,記錄到relay log中繼日志中
- slave再開啟一個sql線程讀取relay log事件并在slave執行,完成同步
- slave記錄自己的binglog
-
怎麼處理主庫挂了
-
:主庫寫入binlog後全同步複制
日志到從庫,強制同步
都執行完成後才傳回給用戶端所有從庫
-
: 解決資料丢失的問題。從庫寫入日志成功後傳回半同步複制
确認給主庫,主庫收到ACK
的确認就認為寫操作完成。至少一個從庫
-
: 解決從庫複制延遲的問題并行複制
-