1. 程式人生 > >MySql 三大知識點——索引、鎖、事務,詳解

MySql 三大知識點——索引、鎖、事務,詳解

開發十年,就只剩下這套架構體系了! >>>   

作者:莫那魯道

來源:http://thinkinjava.cn/2019/03/16/2019-03-16-mysql

1.索引

索引,類似書籍的目錄,可以根據目錄的某個頁碼立即找到對應的內容。

索引的優點:1. 天生排序,2. 快速查詢。

索引的缺點:1. 佔用空間,2. 降低更新表的速度。

注意點:小表使用全表掃描更快,中大表才使用索引。超級大表索引基本無效。

索引從實現上說,分成 2 種:聚集索引和輔助索引(也叫二級索引或者非聚集索引)

從功能上說,分為 6 種:普通索引,唯一索引,主鍵索引,複合索引,外來鍵索引,全文索引。

詳細說說 6 種索引:

1、普通索引:最基本的索引,沒有任何約束。 2、唯一索引:與普通索引類似,但具有唯一性約束。 3、主鍵索引:特殊的唯一索引,不允許有空值。 4、複合索引:將多個列組合在一起建立索引,可以覆蓋多個列。 5、外來鍵索引:只有InnoDB型別的表才可以使用外來鍵索引,保證資料的一致性、完整性和實現級聯操作。 6、全文索引:MySQL 自帶的全文索引只能用於 InnoDB、MyISAM ,並且只能對英文進行全文檢索,一般使用全文索引引擎(ES,Solr)。

注意:主鍵就是唯一索引,但是唯一索引不一定是主鍵,唯一索引可以為空,但是空值只能有一個,主鍵不能為空。

另外,InnoDB 通過主鍵聚簇資料,如果沒有定義主鍵且沒有定義聚集索引, MySql 會選擇一個唯一的非空索引代替,如果沒有這樣的索引,會隱式定義個 6 位元組的主鍵作為聚簇索引,使用者不能檢視或訪問。

簡單點說:

1、設定主鍵時,會自動生成一個唯一索引,如果之前沒有聚集索引,那麼主鍵就是聚集索引。 2、沒有設定主鍵時,會選擇一個不為空的唯一索引作為聚集索引,如果還沒有,那就生成一個隱式的 6 位元組的索引。

MySql 將資料按照頁來儲存,預設一頁為 16kb,當你在查詢時,不會只加載某一條資料,而是將這個資料所在的頁都載入到 pageCache 中,這個其實和 OS 的就近訪問原理類似。

MySql 的索引使用 B+ 樹結構。在說 B+ 樹之前,先說說 B 樹,B 樹是一個多路平衡查詢樹,相較於普通的二叉樹,不會發生極度不平衡的狀況,同時也是多路的。

B 樹的特點是:他會將資料也儲存在非頁子節點。

看圖可知:

而這個特點會導致非頁子節點不能儲存大量的索引。

而 B+ Tree 就是針對這個對 B tree 做了優化。如下圖所示:

我們看到,B+ Tree 將所有的 data 資料都儲存到了葉子節點中,非也子節點只儲存索引和指標。

我們假設一個非頁子節點是 16kb,每個索引,即主鍵是 bigint,即 8b,指標為 8b。那麼每頁能儲存大約 1000 個索引(16kb/ 8b + 8b).

而一顆 3 層的 B+樹能夠儲存多少索引呢?

如下圖:

大約能夠儲存 10 億個索引。通常 B+ 樹的高度在 2-4 層,由於 MySql 在執行時,根節點是常駐記憶體的,因此每次查詢只需要大約 2 -3 次 IO。可以說,B+ 樹的設計,就是根據機械磁碟的特性來進行設計的。

知道了索引的設計,我們能夠知道另外一些資訊:

1、MySql 的主鍵不能太大,如果使用 UUID 這種,將會浪費 B+ 樹的非葉子節點。 2、MySql 的主鍵最好是自增的,如果使用 UUID 這種,每次插入都會調整 B+樹,從而導致頁分裂,嚴重影響效能。

那麼,如果專案中使用了分庫分表,我們通常都會需要一個主鍵進行 sharding,那怎麼辦呢?在實現上,我們可以保留自增主鍵,而邏輯主鍵用來作為唯一索引即可。

2.鎖機制

關於 Mysql 的鎖,各種概念就會噴湧而出,事實上,鎖有好幾種維度,我們來解釋一下。

1.型別維度

共享鎖(讀鎖 / S 鎖) 排它鎖(寫鎖 / X 鎖)

型別細分:

  • 意向共享鎖

  • 意向排他(互斥)鎖

悲觀鎖(使用鎖,即 for update)

樂觀鎖(使用版本號欄位,類似 CAS 機制,即使用者自己控制。缺點:併發很高的時候,多了很多無用的重試)

2.鎖的粒度(粒度維度)

表鎖 頁鎖(Mysql BerkeleyDB 引擎) 行鎖(InnoDB)

3.鎖的演算法(演算法維度)

Record Lock(單行記錄) Gap Lock(間隙鎖,鎖定一個範圍,但不包含鎖定記錄) Next-Key Lock(Record Lock + Gap Lock,鎖定一個範圍,並且鎖定記錄本身, MySql 防止幻讀,就是使用此鎖實現)

4.預設的讀操作,上鎖嗎?

預設是 MVCC 機制(“一致性非鎖定讀”)保證 RR 級別的隔離正確性,是不上鎖的。

可以選擇手動上鎖:select xxxx for update (排他鎖); 

select xxxx lock in share mode(共享鎖),稱之為“一致性鎖定讀”。

使用鎖之後,就能在 RR 級別下,避免幻讀。當然,預設的 MVCC 讀,也能避免幻讀。

既然 RR 能夠防止幻讀,那麼,SERIALIZABLE 有啥用呢?

防止丟失更新。例如下圖:

這個時候,我們必須使用 SERIALIZABLE 級別進行序列讀取。

最後,行鎖的實現原理就是鎖住聚集索引,如果你查詢的時候,沒有正確地擊中索引,MySql 優化器將會拋棄行鎖,使用表鎖。

3.事務

事務是資料庫永恆不變的話題, ACID:原子性,一致性,隔離性,永續性

四個特性,最重要的就是一致性。而一致性由原子性,隔離性,永續性來保證。

原子性由 Undo log 保證。Undo Log 會儲存每次變更之前的記錄,從而在發生錯誤時進行回滾。隔離性由 MVCC 和 Lock 保證。這個後面說。永續性由 Redo Log 保證。每次真正修改資料之前,都會將記錄寫到 Redo Log 中,只有 Redo Log 寫入成功,才會真正的寫入到 B+ 樹中,如果提交之前斷電,就可以通過 Redo Log 恢復記錄。

然後再說隔離性。

隔離級別:

1、未提交讀(RU)

2、已提交讀(RC)

3、可重複讀(RR)

4、序列化(serializable)

每個級別都會解決不同的問題,通常是3 個問題:髒讀,不可重複讀,幻讀。一張經典的圖:

這裡有個注意點,關於幻讀,在資料庫規範裡,RR 級別會導致幻讀,但是,由於 Mysql 的優化,MySql 的 RR 級別不會導致幻讀:在使用預設的 select 時,MySql 使用 MVCC 機制保證不會幻讀;

你也可以使用鎖,在使用鎖時,例如 for update(X 鎖),lock in share mode(S 鎖),MySql 會使用 Next-Key Lock 來保證不會發生幻讀。前者稱為快照讀,後者稱為當前讀。

原理剖析:

1、RU 發生髒讀的原因:RU 原理是對每個更新語句的行記錄進行加鎖,而不是對整個事務進行加鎖,所以會發生髒讀。而 RC 和 RR 會對整個事務加鎖。 2、RC 不能重複讀的原因:RC 每次執行 SQL 語句都會生成一個新的 Read View,每次讀到的都是不同的。而 RR 的事務從始至終都是使用同一個 Read View。 3、RR 不會發生幻讀的原因: 上面說過了。

那 RR 和 Serializble 有什麼區別呢?答:丟失更新。本文關於鎖的部分已經提到。

MVCC 介紹:全稱多版本併發控制。

innoDB 每個聚集索引都有 4 個隱藏欄位,分別是主鍵(RowID),最近更改的事務 ID(MVCC 核心),Undo Log 的指標(隔離核心),索引刪除標記(當刪除時,不會立即刪除,而是打標記,然後非同步刪除);

本質上,MVCC 就是用 Undo Log 連結串列實現。

MVCC 的實現方式:事務以排它鎖的方式修改原始資料,把修改前的資料存放於 Undo Log,通過回滾指標與資料關聯,如果修改成功,什麼都不做,如果修改失敗,則恢復 Undo Log 中的資料。

多說一句,通常我們認為 MVCC 是類似樂觀鎖的方式,即使用版本號,而實際上,innoDB 不是這麼實現的。當然,這不影響我們使用 MySql。

更多技術乾貨

 

近期100多篇技術乾貨,升職加薪必看

百度、騰訊、阿里、谷歌 面試題視訊詳解合集

深入 Redis 主從複製的原理詳解

ZooKeeper 一致性協議 ZAB 原理

Google 出品的 Java 編碼規範,權威又科學

46張PPT講述JVM、GC演算法和效能調優

基於 Zookeeper 的分散式鎖實現

30 道 Dubbo 面試題及答案

RDB 和 AOF 持久化的原理是什麼?

相關推薦

MySql 三大知識點——索引事務

不包含 rdquo solr 選擇 圖片 最好 分表 高度 由於 1. 索引 索引,類似書籍的目錄,可以根據目錄的某個頁碼立即找到對應的內容。 索引的優點:1. 天生排序。2. 快速查找。索引的缺點:1. 占用空間。2. 降低更新表的速度。 註意點:小表使用全表掃描更

MySql 三大知識點——索引事務

開發十年,就只剩下這套架構體系了! >>>   

Mysql數據庫分布式事務XA

oar 存儲引擎 成了 from get 分布式事務 value ive 進展 XA事務簡介 XA 事務的基礎是兩階段提交協議。需要有一個事務協調者來保證所有的事務參與者都完成了準備工作(第一階段)。如果協調者收到所有參與者都準備好的消息,就會通知所有的事務都可以提交了(第

廣度深度易用性6大機器學習雲

我們所謂的“機器學習”可能表現為多種形式。最純粹的機器學習技術為分析師提供了一系列資料探索工具,豐富的機器學習模型,健壯的解決方案演算法,以及通過解決方案進行預測的方法。Amazon、Microsoft、Databricks、Google以及IBM雲平臺都提供了預測API,

spring的事務註解@Transactional

事務管理是應用系統開發中必不可少的一部分。Spring 為事務管理提供了豐富的功能支援。 Spring 事務管理分為程式設計式和宣告式的兩種方式。 程式設計式事務指的是通過編碼方式實現事務,程式設計式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransaction

數據庫的數據類型索引事務和視圖

ima -m log_file oat 寬度 默認值 col 說明 prim 數據庫的數據類型、索引、鎖、事務和視圖 數據的類型 1)數據類型: 數據長什麽樣? 數據需要多少空間來存放? 系統內置數據類型和用戶定義數據類型 2)MySql 支持多種列

MySQL中的行級表級頁級

常用 一點 存儲引擎 rac 鎖定 方法 線程 加鎖 計算機      在計算機科學中,鎖是在執行多線程時用於強行限制資源訪問的同步機制,即用於在並發控制中保證對互斥要求的滿足。   在DBMS中,可以按照鎖的粒度把數據庫鎖分為行級鎖(INNODB引擎)、表級鎖(MYISA

【資料庫視訊】事務系統與原資料函式BEGIN…END

一、事務 管理語句: BEGIN  TRANSACTION(開啟) COMMIT  TRANSACTION(提交) ROLLBACK  TRANSACTION(回滾) SAVE  TRANSACTION(儲存)

MySQL 中的行級表級和頁級(不看後悔看了必懂)

行級鎖 行級鎖是 MySQL 中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖分為共享鎖和排他鎖。 特點:加鎖開銷大,會出現死鎖,鎖定粒度最小,發生鎖衝突的概率最低,併發度最高 頁級鎖 頁級鎖是 MySQL 中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。

優化mysql實驗(explain;索引)+利用 indexexplain和profile優化mysql資料庫查詢小結

1.優化實驗 實驗環境: 1、sql工具:Navicat2、sql資料庫,使用openstack資料庫作為示例 一、mysql索引查詢 show index from instances 結果欄

mysql簡單的索引和inorunion unionall語句查詢速度

MYSQL描述: 一個文章庫,裡面有兩個表:category和article。category裡面有10條分類資料。article裡面有20萬條。article裡面有一個"article_category"欄位是與category裡的"category_id"欄位相對應的。

資料庫事務中的隔離級別spring Transactional註解

資料庫事務中的隔離級別和鎖 資料庫事務在後端開發中佔非常重要的地位,如何確保資料讀取的正確性、安全性也是我們需要研究的問題。 ACID 首先總結一下資料庫事務正確執行的四個要素(ACID): 原子性(Atomicity):即事務是不可分割的最小工作單元,事務內的操作要麼全做,要麼全

詳述 MySQL 中的行級表級和頁級

在電腦科學中,鎖是在執行多執行緒時用於強行限制資源訪問的同步機制,即用於在併發控制中保證對互斥要求的滿足。 在資料庫的鎖機制中,咱們介紹過在 DBMS 中,可以按照鎖的粒度把資料庫鎖分為行級鎖(InnoDB 引擎)、表級鎖(MyISAM 引擎)和頁級鎖(BDB

對資料庫事務隔離級別封鎖協議的理解及其關係的理解

前言 寫篇文章來鞏固自己學習的知識。通過寫文章,本著一顆不誤導別人、不混過去的心,找出那些自己看似懂了的問題。這篇文章主要講的是事務、隔離級別、鎖、封鎖協議之間的關聯。我覺得最重要的是要將這些知識關聯起來。而不是單獨的去理解。 在這裡提一個問題。在瞭解一級封

二:mysql安裝配置主從復制配置

連接 rom con mon 登錄mysql you drop user sysconf type 作者:NiceCui 本文謝絕轉載,如需轉載需征得作者本人同意,謝謝。 本文鏈接:http://www.cnblogs.com/NiceCui/p/8213723.html

Zookeeper技術:分布式架構分布式技術分布式事務

cas 序列號 隔離性 googl 管理系 實現 分布式數據庫 備份 分布式文件系 一、分布式架構詳解 1、分布式發展歷程 1.1 單點集中式 特點:App、DB、FileServer都部署在一臺機器上。並且訪問請求量較少 1.2? 應用服務和數據服務拆分 ?特點:App、

mysql基礎-資料庫連線建立刪除選擇等基本操作(一)

一、通過cmd連結到資料庫 或者 彈出: 二、通過cmd建立與刪除database 2.1create database [databasename] ERROR 1007 (HY000): Can’t create database ‘mytest’; database exists 加上IF N

python之路-day31-守護程序佇列生產者消費者模型

  一、守護程序     之前我們講的子程序是不會隨著主程序而結束的,子程序全部執行完之後,程式才結束,那麼如果有   一天我們的需求是我的主程序結束了,由主程序建立的子程序必須跟著結束,怎麼辦?守護程序就來了!     主程序建立守護程序       其一:守護程序會在主程序程式碼執行結

MySQL之聚合查詢子查詢合併查詢正則表示式查詢

一:聚合查詢 1:MySQL之聚合函式 基本表orderitems表結構如下: 2:count()函式 2.1:count()函式用來統計記錄的條數 2.2:與group by 關鍵字一起使用 SQL語句如下: 查詢的結果如下: 3:su

win10下MYSQL的下載安裝以及配置超教程

下載MYSQL  官網下載MYSQL5.7.21版本,連結地址https://www.mysql.com/downloads/。下載流程圖如下:    進入官網點選Community,下載社群版。    找到MYSQL Community Server,點選下方DOW