【MYSQL】索引和事務

🥰🥰🥰來都來了,不妨點個關注叭!
👉博客主頁:歡迎各位大佬!👈

在這里插入圖片描述
本期內容講解 MySQL 中的索引和事務,在學習的過程中,我們需要經常問自己為什么

文章目錄

  • 1. 索引
    • 1.1 索引的概念
    • 1.2 索引的目的
      • 1.2.1 為什么使用索引會加快查詢速度?
    • 1.3 索引的使用
    • 1.4 索引的分類
    • 1.5 索引的優缺點
    • 1.6 MySQL 的默認存儲引擎 InnoDB 背后的數據結構 —— B+ 樹
      • 1.6.1 B樹
      • 1.6.2 B+樹
  • 2. 事務
    • 2.1 事務的概念
    • 2.2 事務的使用
    • 2.3 事務的四大特性 —— ACID
      • 2.3.1 原子性
      • 2.3.2 一致性
      • 2.3.3 持久性
      • 2.3.4 隔離性
        • 1) 臟讀
        • 2)不可重復讀
        • 3)幻讀

1. 索引

1.1 索引的概念

概念】索引是一種特殊的文件,包含著對數據表里所有記錄的引用指針,可以對表中的一列或多列創建索引,并指定索引的類型,各類索引有各自的數據結構實現 ~

1.2 索引的目的

目的】就比如說,本期文章帶有目錄(筆者每篇文章都帶有目錄)~ 通過目錄,我們就對這期內容有一個大致的了解,并且通過目錄,我們可以快速的定位我們想要的內容,而索引的作用和目錄的作用類似,都是加快查詢速度~

1.2.1 為什么使用索引會加快查詢速度?

首先我們知道,MySQL 數據庫文件存儲在磁盤上的,磁盤 I/O 是數據庫操作比較耗時的一部分

  • 無索引,數據庫會進行全表掃描,它必須讀取表中的每一行數據來查找匹配的行,時間效率為 O(n),當表的數據量非常大時,就會導致大量的磁盤 I/O 操作,非常耗時間!
  • 有索引,可以直接跳到索引指示的數據位置,不用掃描整張表,大大減少了磁盤 I/O 操作的次數,減少時間,如 MySQL 的默認存儲引擎 InnoDB 默認使用 B+ 樹來作為索引的數據結構 ,而 B+ 樹的查詢效率非常高,時間復雜度是O(logN)!(本期內容后面將會具體介紹 B+ 樹)

我們知道索引是一種特殊的文件,MySQL 索引文件主要存儲索引,數據庫文件存儲的數據不僅包括全部數據,還包括索引等信息,索引文件與數據庫文件相比,體積小很多,通過查詢索引,再映射到數據庫記錄,查詢效率就會高很多~

舉例
還是結合目錄來看,通過目錄可以快速定位到哪一個位置,比如查字典,可以通過目錄,快速找到需要的內容在哪一頁,沒有目錄的話,我需要從字典的第一頁,每一頁一頁的翻,找到想要的內容,想想是不是很耗時呢?索引的作用也是如此!加快查詢的作用!

1.3 索引的使用

情況一】對于創建主鍵約束唯一約束外鍵約束時,會自動創建對應列的索引

  1. 首先創建一個 student 表,以 id 為主鍵(此時創建了主鍵約束,會自動創建對應列的索引)
 create table student (id int primary key,username varchar(50));

在這里插入圖片描述

  1. 查看索引
 show index from 表名;

從下圖中可以看到,主鍵 id,自動創建了索引
在這里插入圖片描述
如果 id 沒有加主鍵約束,是不會自動創建索引的~ 如下圖:

在這里插入圖片描述
情況二創建普通索引,對于非主鍵、非唯一約束、非外鍵的字段,可以創建普通索引

  1. 創建索引
create index 索引名 on 表名(列名);

在這里插入圖片描述

  1. 刪除索引
drop index 索引名 on 表名;

在這里插入圖片描述

(可以動手多操作哦,才會記憶深刻呀~更加利于理解哦!)

1.4 索引的分類

在這里插入圖片描述

1.5 索引的優缺點

優點

  • 加快查詢速度:通過索引可以快速定位到滿足查詢條件的數據行,減少數據的掃描范圍,從而提高查詢效率。例如,在一個包含大量用戶信息的表中,如果經常根據用戶姓名進行查詢,為姓名列創建索引后,查詢速度大大提升;
  • 保證數據唯一性:可以通過創建唯一索引來確保表中某列或某些列組合的數據具有唯一性,防止出現重復數據,比如,在用戶表中,為身份證號碼列創建唯一索引,就可以保證每個用戶的身份證號碼是唯一的;
  • 支持數據排序:索引可以按照指定的列進行排序,當查詢需要對結果進行排序時,使用索引可以避免數據庫在查詢時進行額外的排序操作,提高查詢性能。比如,在訂單表中,為訂單時間列創建索引,當按照訂單時間查詢并排序訂單時,數據庫可以直接使用索引來獲取有序的數據。

缺點

  • 占用存儲空間:索引本身需要占用一定的磁盤空間來存儲索引結構,隨著數據量的增加和索引數量的增多,占用的空間也會相應增大,比如,一個大型數據表創建多個索引后,可能會使數據庫文件的大小增加很多;
  • 增加維護成本:在數據插入、更新和刪除時,索引也需要進行相應的更新操作,這會增加數據庫的維護成本和時間開銷。例如,當向表中插入一條新記錄時,如果該表有多個索引,那么每個索引都需要進行更新以保證索引的準確性和一致性;
  • 降低寫入性能:由于寫入數據時需要同時更新索引,所以會降低寫入操作的性能,比如,在批量插入數據時,沒有索引的表插入速度會比有索引的表快很多

1.6 MySQL 的默認存儲引擎 InnoDB 背后的數據結構 —— B+ 樹

在本期內容開頭就介紹了,數據庫索引的作用是為了加快查詢速度的~ 那么,我們會思考,其索引背后的數據結構是什么呢? 并且能夠讓它加快查詢速度!

我們可以回想一下之前學過的數據結構,其中,二叉搜索樹和哈希表就是比較適合查詢的,但是很遺憾的是,它們兩個都不適合于數據庫索引的底層數據結構:

  • 二叉搜索樹: 二叉搜索樹查找的時間復雜度是樹的高度,我們知道數據庫一般都是將數據存儲在硬盤上,數據量很大的時候,如果使用二叉搜索樹,則樹的高度也會很大,導致查詢效率會很慢,
  • 哈希表:哈希表它是由數組和鏈表組成的,查找的時間復雜度為 O(1),盡管時間復雜度低,但是,它的 key 不是有序的,并且對于數據庫中的大于、小于的范圍查找或者是 LIKE 類似的模糊查詢哈希表都是不能夠做到的,比如,我們要查詢學生的序號在 202110120510 到 202110120534 之間的學生信息,哈希表是做不到的~

噔噔噔!!! 這里,就要介紹一種特殊的數據結構,B+樹 —— 專門為了數據庫索引量身定做的數據結構!

1.6.1 B樹

介紹 B+ 樹前,先介紹一下 B 樹,也叫做 B- 樹,注意!!! 這里的 ‘-’ 不是減號,只是連接符哦! 很多小伙伴看到有 B+ 樹,可能會想當然的以為也有 B- 樹

B樹可以認為是一顆N叉搜索樹,結構如下:

在這里插入圖片描述

我們可以通過圖看到,當節點的子樹多了,節點上保存的 key 就多了,在相同個數 key 的情況下,B 樹的高度就比二叉搜索樹的高度要低很多,對 IO 操作的次數就越少,這樣查找性能就會比較高!

1.6.2 B+樹

我們先來了解一下 B+ 樹的特點~

B+ 樹的特點

  • 一個節點可以存儲 N 個 key,N 個 key 可以劃分出 N 個子區間(不是 N+1 個)
  • 每一個 key 都會在子區間出現,且為子區間的最大值
  • B+ 樹的葉子節點是首尾相連的,類似于一個鏈表
  • B+ 樹的非葉子節點只用于索引并不保存數據,只有葉子節點存儲著索引和數據

到底是一個什么樣的數據結構呢? 我們一起來看看!

在這里插入圖片描述
既然有 B 樹,那么為什么還要有 B+ 樹呢?

我們一起來分析一下 B 樹的優缺點:

  • B樹優點:每個節點都存儲了索引和對應的數據,在查找離根節點近的節點時,查找效率是很高的,不用每次都查找到葉子節點(與B+樹相比,因為 B+ 樹必須得查找到葉子節點)
  • B樹缺點
    不利于范圍查找,即不利于區間查找,比如要找 5 - 14 的索引值,那么 B 樹就需要多次從根節點逐個查找,而 B+ 樹的葉子節點是鏈表連接起來的,且是從小到大依次有序的,在 B+ 樹中,只用找到 5 索引 和 14 索引的葉子節點,從 5 沿著鏈表遍歷到 14 即可!

再來分析一下 B+ 樹的優點:

  • 查詢任意一個節點最終都會落到葉子節點每次 IO 訪問次數是一樣的
  • B+ 樹的所有葉子節點構成了一個完整的鏈表,適合進行范圍查找
  • 只有葉子節點是存儲著完整的數據,非葉子節點只記錄索引,這樣這些非葉子節點占用的內存就十分的小,又進一步減小 IO 操作次數

補充知識

1)回表

比如在有一些表中,有多個索引,如上述創建的 student 表里,我們在 username 這一列創建了一個索引,此時,表的數據還是會根據主鍵id 構建出 B+ 樹,通過葉子節點將數據組織起來,其次,會根據 username 這個列創建一個B+樹,但這個 B+ 樹的葉子節點只存儲主鍵id是什么,此時如果你是通過 username 這個索引來查找的,會通過葉子節點拿到的 id 索引再去由 id 創建的B+樹里再查一次,即查兩次B+樹,上述過程,在數據庫中就叫回表

上述過程是 Mysql 自動完成的,用戶是完全感知不到的,這是因為主鍵索引也是聚簇索引,葉子節點存儲整個數據和索引,而其他索引就是非聚簇索引,葉子節點只存儲主鍵和索引,因此,使用非聚簇索引進行查詢的時候需要再拿著這個查詢到的主鍵再在聚簇索引中進行一次查詢,即回表

2)聚簇索引和非聚簇索引

在 MySQL 的 默認 InnoDB 引擎中,每個索引都會對應一顆 B+ 樹,而聚簇索引和非聚簇索引最大的區別在于葉子節點存儲的數據不同,聚簇索引葉子節點存儲的是行數據,因此通過聚簇索引可以直接找到真正的行數據;而非聚簇索引葉子節點存儲的是主鍵信息,所以使用非聚簇索引還需要回表查詢,因此,我們可以得出聚簇索引和非聚簇索引的區別主要有以下幾個:

  • 存儲內容聚簇索引葉子節點存儲的是行數據;而非聚簇索引葉子節點存儲的是聚簇索引,通常是主鍵 ID;
  • 效率聚簇索引查詢效率更高,而非聚簇索引需要進行回表查詢,因此性能不如聚簇索引;
  • 數量上:聚簇索引一般為主鍵索引,而主鍵一個表中只能有一個,因此聚簇索引一個表中也只能有一個,而非聚簇索引則沒有數量上的限制

2. 事務

2.1 事務的概念

我們先來想一下這個場景,七夕節到了,小丁準備給他的女朋友小萬轉賬 1314,那么 sql 語句應該如下:

update account set  money = money - 1314 where name = ‘小丁’;
update account set  money = money + 1314 where name = ‘小萬’;

假設在執行完第一條語句后,數據庫突然崩潰了或者主機宕機了,此時就出現了問題,小丁的錢扣了,但是小萬沒有收到轉賬,小萬就會很生氣,覺得沒轉就沒轉,而不能這樣騙她!小丁就百口莫辯了,明明自己轉了呀!現實生活中,有很多這樣的支付場景,那么如何解決呢?

事務則是解決上述問題的,事務指的是邏輯上一組操作,組成這組操作的各個單元,要么全部成功,要么全部失敗,在不同環境中,都可以有事務,對應在數據庫中,就是數據庫事務,通俗的來講,就是把 sql 語句打包在一起,要么全部都執行成功,要么全部都不執行,不會出現執行到一半的情況,注意,這里的全部都不執行,并不是真的沒執行,而是執行到一半,出現問題后,選擇恢復到原來的樣子,將數據灰度到未執行的狀態,這個恢復操作,就叫做 “回滾”(rollback)

2.2 事務的使用

  1. 開啟事務:start transaction;
  2. 中間放要執行的 sql 語句
  3. 回滾或提交: rollback/commit;
    (說明: rollback表示“全部失敗”,commit表示“全部成功”)

具體代碼如下:

start transaction; //開啟事務
update account set money = money - 1314 where name = '小丁';
update account set money  =money + 1314 where name = '小萬';
commit;   //提交事務

2.3 事務的四大特性 —— ACID

2.3.1 原子性

事務的初心就是原子性事務是一個不可分割的單位,數據庫事務里的 sql 語句要么全部執行,要么全部不執行,不會出現執行一半的情況,如果執行一半出現問題就會進行 “回滾” 操作(強調事務是一個整體)

2.3.2 一致性

事務執行前后,數據都是一個合法的狀態,就像上面的轉賬情況,在轉賬前和轉賬后數據都應該是一個合法的狀態,是一致的(強調數據的合法狀態)

2.3.3 持久性

事務修改的內容是寫入硬盤的,持久存在,重啟也不會消失(強調事務修改內容都是寫入硬盤的,具有持久性)

2.3.4 隔離性

多個事務并發執行的時候,每個事務應該感受不到其他事務的存在,各個事務是隔離的(強調多個事務并發執行,各事務是隔離的,相互不影響)

但是,不同的事務隔離級別會導致不同的并發問題,如臟讀,不可重復讀,幻讀,下面將具體介紹這三個問題:

1) 臟讀

概念】臟讀就是一個事務讀取到了另一個未提交事務修改的數據

舉例】事務A 對數據庫中的小萬余額進行讀取,余額為 100,接著再執行更新操作,將余額更新為 500,此時,并沒有提交事務,而另一邊,事務B 對數據庫中的小萬余額進行讀取,那么事務B就讀取到了事務A更新的金額,余額為 500,但是此時事務A并沒有提交事務!隨時可能發生回滾操作,如果上述情況事務發生回滾,那么余額為 100,而事務B讀取到了事務A的過期數據500,這個就是臟讀

解決方式】給事務A修改數據這個操作進行寫加鎖當事務A修改數據的時候,其它事務不能對該數據進行讀取,這樣就意味著此時寫操作和讀操作不能并發執行了,降低了并發程度,即降低了小效率,但是提高了隔離性,即提高了數據的準確性

2)不可重復讀

概念】不可重復讀就是一個事務多次重復讀取一個數據,如果出現了前后兩次讀取的數據不一致的情況

舉例】一個事務A對小萬的余額進行讀取,此時有一個事務B對小萬的余額進行更新并提交事務,這樣,事務A對小萬的余額再進行讀取的時候,就會發現,前后兩次讀取的數據不一樣,這就是不可重復讀

解決方式】給事務A對數據進行讀取的時候進行讀加鎖,當事務A對數據進行讀取操作的時候,其它事務不能對該數據進行修改,此時,又降低了并發程度,提高了隔離性

3)幻讀

概念】幻讀就是在一個事務內多次查詢符合條件的記錄數量,出現了前后查詢數量不一致的情況

舉例】事務A在數據庫中查詢余額大于500的用戶,此時有十條記錄,但是事務B此時插入了一條余額大于500的用戶,并提交事務,這個時候事務A再進行查詢余額大于500的用戶,就查詢到十一條記錄,這個就是幻讀

解決方式】數據庫使用 “串行化” 的操作來解決幻讀的問題,就是徹底放棄事務并發,一個接一個的串行執行事務,此時,并發程度最低,效率最低,隔離性最高,數據準確性最高!

數據庫提供的四個隔離級別

  • read uncommitted(讀未提交)
    沒有任何鎖限制,并發程度最高,隔離性最低,會發生上述三種問題
  • read committed(讀已提交)
    給寫加鎖,并發程度降低,隔離性增加,但會產生“不可重復讀”和“幻讀”問題
  • repeatable read(可重復讀)(MySQL的默認隔離級別)
    給讀寫都加鎖,并發程度進一步降低,隔離性進一步增加,但可能會產生“幻讀”問題
  • serializable(串行化)
    徹底實行串行化,并發程度最低,隔離性最高

💛💛💛本期內容回顧💛💛💛
在這里插入圖片描述

???本期內容到此結束啦~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898927.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898927.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898927.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計劃管理工具應該具備的能(甘特圖)

在當今快節奏的項目管理環境中,高效地規劃和跟蹤項目進度是至關重要的。甘特圖,作為項目管理領域的經典工具,以其直觀的時間軸和任務分配方式,深受項目管理者的青睞。 隨著數字化時代的到來,甘特圖線上編輯器應運而生&…

Redis分布式尋址算法

分布式尋址算法是分布式系統中用于確定數據應該存儲在哪個節點的算法。這些算法對于實現高效的數據存取、負載均衡和系統擴展性至關重要。以下是幾種常見的分布式尋址算法的解釋: 1. Hash 算法 原理:通過哈希函數將數據的鍵(Key&#xff09…

CSS動畫

目錄 一、核心概念與語法 1. keyframes 關鍵幀 2. animation 屬性 二、動畫調速函數(animation-timing-function) 1. 預設值 2. 貝塞爾曲線 3. 步進函數(steps()) 三、動畫控制與交互 1. 暫停與恢復 2. JavaScript 控制…

2025年河北省第二屆職業技能大賽網絡安全項目 模塊 B樣題任務書

2025年河北省第二屆職業技能大賽網絡安全項目 模塊 B樣題任務書 河北省第二屆職業技能大賽網絡安全項目-模塊 B-奪旗挑戰賽(CTF)一、目標系統1二、目標系統2三、目標系統3四、目標系統4 需要真題環境-培訓可以私信博主! 河北省第二屆職業技能…

鈔票準備好了嗎?鴻蒙電腦 5 月見

3月20日,在華為 Pura 先鋒盛典及鴻蒙智行新品發布會上,華為常務董事、終端BG董事長、智能汽車解決方案BU董事長余承東表示,華為終端全面進入鴻蒙時代,今年5月將推出鴻蒙電腦。 在3月20日的華為Pura先鋒盛典及鴻蒙智行新品發布會上…

Java高頻面試之集合-15

hello啊,各位觀眾姥爺們!!!本baby今天來報道了!哈哈哈哈哈嗝🐶 面試官:解決哈希沖突有哪些方法? 1. 開放尋址法(Open Addressing) 核心思想:當哈…

【機器學習】建模流程

1、數據獲取 1.1 來源 數據獲取是機器學習建模的第一步,常見的數據來源包括數據庫、API、網絡爬蟲等。 數據庫是企業內部常見的數據存儲方式,例如:MySQL、Oracle等關系型數據庫,以及MongoDB等非關系型數據庫,它們能夠…

GitHub 上的 Khoj 項目:打造你的專屬 AI 第二大腦

在信息爆炸的時代,高效管理和利用個人知識變得愈發重要。GitHub 上的 Khoj 項目為我們提供了一個強大的解決方案,它能成為你的 “AI 第二大腦”,幫你輕松整合、搜索和運用知識。今天,就來詳細了解下 Khoj。? Khoj 是什么&#x…

爬蟲(requsets)筆記

一、request_基本使用 pip install requests -i https://pypi.douban.com/simple 一個類型六個屬性 r.text 獲取網站源碼 r.encoding 訪問或定制編碼方式r.url 獲取請求的urlr.content 響應的字節類型r.status_code 響應的狀態碼r.headers 響應的頭信息 import requestsur…

centos7連不上接網絡

選擇編輯, 選擇虛擬機網絡編輯 右鍵虛擬機,點擊設置,設置網絡,選擇nat模式, 配置:/etc/sysconfig/network-scripts/ifcfg-ens33 vim /etc/sysconfig/network-scripts/ifcfg-ens33設置IP地址如圖所示,重…

OpenResty(Lua)+Redis實現動態封禁IP

文章目錄 架構設計環境準備源碼編輯安裝OpenResty下載安裝準備依賴編譯安裝配置環境變量(可選)OpenResty 服務管理命令 安裝Redis配置Lua腳本測試準備測試工具測試封禁邏輯 刪除版本信息清除編譯安裝的OpenResty 架構設計 通過 Nginx Redis 的方案&…

Turtle基本操作(前進、后退、旋轉)

1. Turtle基本移動概念 在Turtle繪圖中,“海龜”(Turtle)相當于一支筆,它在屏幕上移動時,會在經過的路徑上留下軌跡。我們可以通過一系列簡單的指令控制它的前進、后退和旋轉,從而繪制各種形狀和圖案。 2. 前進與后退 2.1 前進(forward() 或 fd()) Turtle的 forward…

C++類與對象的第一個簡單的實戰練習-3.24筆記

在嗶哩嗶哩學習的這個老師的C面向對象高級語言程序設計教程&#xff08;118集全&#xff09;講的真的很不錯 實戰一&#xff1a; 情況一&#xff1a;將所有代碼寫到一個文件main.cpp中 #include<iostream> //不知道包含strcpy的頭文件名稱是什么,問ai可知 #include<…

Jetson Orin NX使用 Ollama 本地部署 deepseek

本文記錄在 jetson orin nx 上使用 ollama 部署 deepseek 的過程 有用的網站及工具 NVIDIA Jetson AI LabOllama官網Jtop 工具 > 用以查看jetson GPU/CPU/Memory 等占用情況的工具&#xff0c;安裝過程如下&#xff1a; sudo apt-get install python3-pip sudo -H pip3 in…

目標檢測20年(三)

對這篇論文感興趣的小伙伴可以訂閱筆者《目標檢測》專欄&#xff0c;關注筆者對該文獻的閱讀和理解。 前兩篇解讀鏈接&#xff1a; 目標檢測20年&#xff08;一&#xff09;-CSDN博客 目標檢測20年&#xff08;二&#xff09;-CSDN博客 目錄 四、 檢測器的加速發展 4.1 特…

智能手持終端PDA在設備巡檢管理中的應用

在工業制造、能源電力、軌道交通等領域&#xff0c;設備巡檢是保障生產安全與連續性的核心環節。傳統巡檢模式存在效率低、易出錯、數據滯后等痛點。上海岳冉智能設備巡檢手持終端PDA&#xff0c;以智能化、數字化、高可靠為核心設計理念&#xff0c;集RFID、條碼掃描、AI圖像識…

AI知識補全(二):提示工程(Prompting)是什么?

名人說&#xff1a;人生如逆旅&#xff0c;我亦是行人。 ——蘇軾《臨江仙送錢穆父》 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;AI知識補全&#xff08;一&#xff09;&#xff1a;tokens是什么…

C++友元:跨墻訪問的三種姿勢

目錄 友元 友元之普通函數形式 友元之成員函數形式 友元類 友元的特點 友元 什么叫友元&#xff1f; 一般來說&#xff0c;類的私有成員只能在類的內部訪問&#xff0c;類之外是不能訪問它們的。但如果將其他類/函數設置為類的友元&#xff0c;那么友元類/函數就可以在前…

位運算[找出唯一成對的數]

題目來源&#xff1a;藍橋云課 不用輔助儲存空間 import java.util.Random;public class T_01 {public class Util {public static void swap(int[] arr, int i, int j) {int temp arr[i];arr[i] arr[j];arr[j] temp;}public static void print(int[] arr) {for (int i 0; …

簡記_FPGA 硬件最小系統設計

一、FPGA板級設計的五要素 1.1、電源電路 核心電壓&#xff1a;一般為固定值 IO電壓&#xff1a;FPGA的IO分為多個bank&#xff0c;同一個bank的不同IO引腳電壓相同&#xff0c;不同bank的電壓可以不同 輔助電壓&#xff1a;除了核心電壓和IO電壓&#xff0c;FPGA工作所需的…