MySQL中行級(jí)鎖和表級(jí)鎖的區(qū)別小結(jié)
MySQL 中的行級(jí)鎖和表級(jí)鎖是兩種不同的鎖機(jī)制,它們?cè)诓l(fā)控制和鎖粒度方面有顯著的區(qū)別。了解這兩種鎖的區(qū)別及其使用場(chǎng)景,有助于優(yōu)化數(shù)據(jù)庫(kù)性能并確保數(shù)據(jù)一致性。以下是對(duì)行級(jí)鎖和表級(jí)鎖的詳細(xì)解析,并結(jié)合代碼示例來(lái)幫助理解。
一、行級(jí)鎖 vs 表級(jí)鎖
1. 行級(jí)鎖(Row-level Locks)
- 粒度:行級(jí)鎖鎖定的是表中的單個(gè)行。
- 并發(fā)性:行級(jí)鎖具有較高的并發(fā)性能,因?yàn)椴煌聞?wù)可以并發(fā)地修改不同的行。
- 開銷:管理行級(jí)鎖的開銷較高,因?yàn)樾枰櫭恳恍械逆i狀態(tài)。
- 使用場(chǎng)景:適用于需要高并發(fā)讀寫操作的場(chǎng)景。
2. 表級(jí)鎖(Table-level Locks)
- 粒度:表級(jí)鎖鎖定的是整個(gè)表。
- 并發(fā)性:表級(jí)鎖的并發(fā)性能較低,因?yàn)橐粋€(gè)事務(wù)鎖定整個(gè)表后,其他事務(wù)不能同時(shí)對(duì)該表進(jìn)行任何讀寫操作。
- 開銷:管理表級(jí)鎖的開銷較低,相對(duì)于行級(jí)鎖而言更簡(jiǎn)單。
- 使用場(chǎng)景:適用于讀多寫少的場(chǎng)景,如報(bào)表查詢等。
二、InnoDB 中的行級(jí)鎖
InnoDB 存儲(chǔ)引擎支持行級(jí)鎖,這使得它適用于高并發(fā)的事務(wù)處理。
1. 共享鎖(S-lock)
多個(gè)事務(wù)可以同時(shí)讀取同一行,但不能修改。
START TRANSACTION; -- 獲取共享鎖 SELECT * FROM employees WHERE id = 1 LOCK IN SHARE MODE; -- 完成事務(wù) COMMIT;
2. 排它鎖(X-lock)
一個(gè)事務(wù)獲取排它鎖后,其他事務(wù)不能讀取或修改該行。
START TRANSACTION; -- 獲取排它鎖 SELECT * FROM employees WHERE id = 1 FOR UPDATE; -- 完成事務(wù) COMMIT;
三、MyISAM 中的表級(jí)鎖
MyISAM 存儲(chǔ)引擎只支持表級(jí)鎖。
1. 讀鎖(共享鎖)
多個(gè)客戶端可以同時(shí)讀取表,但不能寫入。
LOCK TABLES employees READ; -- 在鎖定的表上執(zhí)行讀操作 SELECT * FROM employees; -- 釋放鎖 UNLOCK TABLES;
2. 寫鎖(排它鎖)
一個(gè)客戶端獲取寫鎖后,其他客戶端不能讀取或?qū)懭朐摫怼?/p>
LOCK TABLES employees WRITE; -- 在鎖定的表上執(zhí)行寫操作 INSERT INTO employees (name, department_id) VALUES ('Alice', 1); -- 釋放鎖 UNLOCK TABLES;
四、使用示例
1. 行級(jí)鎖示例
假設(shè)有一個(gè) employees
表,我們使用 InnoDB 存儲(chǔ)引擎,并展示行級(jí)鎖的使用。
CREATE TABLE employees ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, department_id INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB; INSERT INTO employees (name, department_id) VALUES ('Alice', 1), ('Bob', 2);
兩會(huì)話并發(fā)更新不同的行:
- 會(huì)話 1
START TRANSACTION; UPDATE employees SET name = 'Charlie' WHERE id = 1; -- 保持事務(wù)未提交
- 會(huì)話 2
START TRANSACTION; UPDATE employees SET name = 'Dave' WHERE id = 2; -- 保持事務(wù)未提交
這種情況下,兩會(huì)話可以并發(fā)執(zhí)行,因?yàn)樗鼈冃薷牡氖遣煌男小?/p>
2. 表級(jí)鎖示例
假設(shè)有一個(gè) employees
表,我們使用 MyISAM 存儲(chǔ)引擎,并展示表級(jí)鎖的使用。
CREATE TABLE employees ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, department_id INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=MyISAM; INSERT INTO employees (name, department_id) VALUES ('Alice', 1), ('Bob', 2);
兩會(huì)話并發(fā)更新表:
- 會(huì)話 1
LOCK TABLES employees WRITE; UPDATE employees SET name = 'Charlie' WHERE id = 1; -- 保持鎖未釋放
- 會(huì)話 2
-- 會(huì)被阻塞,直到會(huì)話 1 釋放鎖 LOCK TABLES employees WRITE; UPDATE employees SET name = 'Dave' WHERE id = 2;
這種情況下,會(huì)話 2 會(huì)被阻塞,直到會(huì)話 1 釋放鎖,因?yàn)?MyISAM 使用的是表級(jí)鎖。
五、意向鎖
InnoDB 還支持意向鎖(Intent Locks),這是表級(jí)鎖和行級(jí)鎖之間的一種協(xié)調(diào)機(jī)制。意向鎖分為意向共享鎖(IS)和意向排它鎖(IX)。
- 意向共享鎖(IS-lock):事務(wù)打算在某些行上加共享鎖時(shí),先在表級(jí)加意向共享鎖。
- 意向排它鎖(IX-lock):事務(wù)打算在某些行上加排它鎖時(shí),先在表級(jí)加意向排它鎖。
意向鎖是由 InnoDB 自動(dòng)管理的,不需要顯式加鎖。
六、總結(jié)
行級(jí)鎖和表級(jí)鎖是 MySQL 中兩種重要的鎖機(jī)制,它們?cè)阪i粒度和并發(fā)控制方面有顯著的區(qū)別:
- 行級(jí)鎖:粒度較小,適合高并發(fā)讀寫操作,但管理開銷較高。InnoDB 存儲(chǔ)引擎支持行級(jí)鎖。
- 表級(jí)鎖:粒度較大,適合讀多寫少的場(chǎng)景,管理開銷較低。MyISAM 存儲(chǔ)引擎使用表級(jí)鎖。
通過(guò)合理選擇和使用鎖機(jī)制,可以有效提高數(shù)據(jù)庫(kù)的并發(fā)性能和數(shù)據(jù)一致性。理解和掌握這些鎖機(jī)制的細(xì)節(jié),有助于在設(shè)計(jì)和優(yōu)化數(shù)據(jù)庫(kù)時(shí)做出更好的決策。
到此這篇關(guān)于MySQL中行級(jí)鎖和表級(jí)鎖的區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)MySQL 行級(jí)鎖和表級(jí)鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL如何實(shí)現(xiàn)負(fù)載均衡功能
這篇文章主要介紹了MySQL如何實(shí)現(xiàn)負(fù)載均衡功能,學(xué)習(xí)過(guò)數(shù)據(jù)庫(kù)的朋友們都會(huì)知道MySQL,那么如何在MySQL下實(shí)現(xiàn)負(fù)載均衡功能呢?本文就將為大家細(xì)致地介紹一下2019-06-06一文詳解如何在MySQL中處理JSON數(shù)據(jù)
在當(dāng)今的大數(shù)據(jù)時(shí)代,JSON作為一種輕量級(jí)的數(shù)據(jù)交換格式,被廣泛應(yīng)用于Web應(yīng)用的數(shù)據(jù)傳輸,隨著MySQL 5.7的發(fā)布,MySQL引入了對(duì)JSON數(shù)據(jù)類型的支持,本文將詳細(xì)介紹如何在MySQL中處理JSON數(shù)據(jù),并提供示例,需要的朋友可以參考下2024-08-08MySQL數(shù)據(jù)庫(kù)崩潰問題的檢測(cè)與解決方法
數(shù)據(jù)庫(kù)崩潰問題可能會(huì)對(duì)系統(tǒng)的可用性和數(shù)據(jù)的完整性造成嚴(yán)重影響,這篇文章主要為大家詳細(xì)介紹了MySQL如何解決數(shù)據(jù)庫(kù)崩潰問題,需要的小伙伴可以了解下2025-07-07MySQL主從同步診斷show?slave?status?卡住的深度排查與解決方案(最新推薦)
在?MySQL主從架構(gòu)的日常運(yùn)維中,show?slave?status是監(jiān)控同步狀態(tài)的核心命令,本文結(jié)合源碼分析與調(diào)試實(shí)踐,揭示其背后的鎖競(jìng)爭(zhēng)機(jī)制,并提供系統(tǒng)性的排查與優(yōu)化方案,感興趣的朋友一起看看吧2025-06-06MySQL創(chuàng)建數(shù)據(jù)庫(kù)和創(chuàng)建數(shù)據(jù)表
MySQL?是最常用的數(shù)據(jù)庫(kù),在數(shù)據(jù)庫(kù)操作中,基本都是增刪改查操作,簡(jiǎn)稱CRUD。但是,這篇文章主要介紹了數(shù)據(jù)庫(kù)和數(shù)據(jù)表如何創(chuàng)建,想詳細(xì)了解的小伙伴可以參考閱讀一下2023-03-03MySQL 中 ROW_NUMBER() 函數(shù)最佳實(shí)踐
MySQL中ROW_NUMBER()函數(shù),作為窗口函數(shù)為每行分配唯一連續(xù)序號(hào),區(qū)別于RANK()和DENSE_RANK(),特別適合分頁(yè)、去重、TopN等需要精確順序控制的場(chǎng)景,本文給大家介紹MySQL中ROW_NUMBER()函數(shù),感興趣的朋友一起看看吧2025-06-06