Mysql常用的存儲(chǔ)引擎對(duì)比
- MyISAM 強(qiáng)調(diào)的是性能,執(zhí)行更快,但不支持事務(wù),InnoDB支持事務(wù)
- MyISAM不支持外鍵,InnoDB支持
- MyISAM只支持表索,InnoDB行鎖表索都支持,行鎖基于索引(只有通過索引查詢時(shí)行鎖才有效)
- 當(dāng)數(shù)據(jù)量很大又不需要支持事務(wù)時(shí)最好選擇MyISAM
- 對(duì)于UPDATE、DELETE、INSERT語句,InnoDB會(huì)自動(dòng)給涉及數(shù)據(jù)集加排他鎖,一般情況下不需要手動(dòng)加鎖
Mysql的存儲(chǔ)結(jié)構(gòu)
系統(tǒng)從磁盤讀取數(shù)據(jù)到內(nèi)存以塊(block)為單位,Mysql數(shù)據(jù)存儲(chǔ)在磁盤中,以頁為單位,默認(rèn)每頁16k,系統(tǒng)磁盤塊一般沒有這么大,所以一般是使用連續(xù)的若干個(gè)塊來構(gòu)成頁
InnoDB存儲(chǔ)引擎中頁的大小為16KB,一般表的主鍵類型為INT(占用4個(gè)字節(jié))或BIGINT(占用8個(gè)字節(jié)),指針類型也一般為4或8個(gè)字節(jié),也就是說一個(gè)頁(B+Tree中的一個(gè)節(jié)點(diǎn))中大概存儲(chǔ)16KB/(8B+8B)=1K個(gè)鍵值(因?yàn)槭枪乐担瑸榉奖阌?jì)算,這里的K取值為10^3)。 也就是說一個(gè)深度為3的B+Tree索引可以維護(hù)10^3 * 10^3 * 10^3 = 10億 條記錄。
Mysql的數(shù)據(jù)庫索引
- 索引會(huì)加快查詢的效率,但是會(huì)降低新增、修改、刪除的效率
- 哈希索引:底層的數(shù)據(jù)結(jié)構(gòu)就是哈希表,在絕大多數(shù)需求為單條記錄查詢的時(shí)候,可以選擇哈希索引,查詢性能最快
- BTree索引:底層為B+樹,可作為大多數(shù)情況使用
B+樹的查找過程如下圖

數(shù)據(jù)庫悲觀鎖和樂觀鎖
- 悲觀鎖
加了寫鎖以后,其他的事務(wù)就不能對(duì)它修改了!
select * from xxxx for update
- 樂觀鎖
通過給表增加版本號(hào)來實(shí)現(xiàn),更新時(shí)對(duì)比版本號(hào)
update A set Name=lisi,version=version+1 where ID=#{id} and version=#{version}
常見數(shù)據(jù)庫優(yōu)化手段
- 讀/寫分離:主庫負(fù)責(zé)寫,從庫負(fù)責(zé)讀
- 增加緩存
- 字段較多的表可拆表
- 數(shù)據(jù)量大的表可分表(Sharding-JDBC )
Mysql事務(wù)隔離級(jí)別
事務(wù)的四大基本要素(ACID):原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation,同一時(shí)間不同事務(wù)間沒有干擾)、持久性(Durability,事務(wù)完成后數(shù)據(jù)被持久化)
事務(wù)的并發(fā)問題:臟讀(讀到了其他事務(wù)未提交的數(shù)據(jù))、不可重復(fù)讀(事務(wù)期間多次讀取的數(shù)據(jù)不一致)、幻讀(一個(gè)事務(wù)改全表多條數(shù)據(jù)期間,另一進(jìn)程插入數(shù)據(jù)導(dǎo)致全表更新結(jié)果不完整,解決幻讀需鎖表)
| 事務(wù)隔離級(jí)別 | 臟讀 | 不可重復(fù)讀 | 幻讀 | 解釋 |
|---|---|---|---|---|
| 讀未提交(read-uncommitted) | 是 | 是 | 是 | 允許讀取其他事務(wù)未提交的數(shù)據(jù) |
| 不可重復(fù)讀(read-committed) | 否 | 是 | 是 | 只讀取其他事務(wù)已提交的數(shù)據(jù) |
| 可重復(fù)讀(repeatable-read) | 否 | 否 | 是 | select操作不更新版本號(hào),后續(xù)重復(fù)讀取的是歷史版本,update/insert/delete操作時(shí)讀取最新版本 |
| 串行化(serializable) | 否 | 否 | 否 | 操作串行化、鎖表,事務(wù)操作時(shí)全表不允許其他線程修改,并發(fā)極低,很少用 |
Mysql默認(rèn)使用repeatable-read級(jí)別,有索引時(shí),默認(rèn)使用next-key鎖(鎖定數(shù)據(jù)及前后幾條,一定程度上避免幻讀)。如果檢索條件沒有索引,更新數(shù)據(jù)時(shí)會(huì)鎖住整張表!