?感謝您閱讀本篇文章,文章內容是個人學習筆記的整理,如果哪里有誤的話還請您指正噢?
? 個人主頁:余輝zmh–CSDN博客
? 文章所屬專欄:MySQL篇–CSDN博客
文章目錄
- 索引
- 一.MySQL與存儲
- 二.索引的理解
- 1.Page頁模式
- 理解單個Page
- 理解多個Page
- 2.頁目錄
- 單頁情況優化
- 多頁情況優化
- 3.B樹 VS B+樹
- B樹(B-Tree)結構
- B+樹(B+Tree)結構
- 4.聚簇索引 VS 非聚簇索引
- 聚簇索引
- 非聚簇索引
- 三.索引的操作
- 創建索引
- 查詢索引
- 刪除索引
- 查詢索引
- 刪除索引
索引
一.MySQL與存儲
MySQL
給用戶提供存儲服務,而存儲的都是數據,數據在磁盤這個外設當中;但是磁盤是計算機中的一個機械設備,相比于其他的電子元件,磁盤效率是比較低的,再加上IO本身的特征,可以知道,如何提交IO效率,是MySQL
的一個重要話題(接下來的內容全部都是圍繞這個話題來展開)。
1.MySQL,系統和磁盤三者之間的IO交互
現代操作系統的內存被劃分為兩個主要區域:
-
用戶空間:應用程序運行的地方,MySQL服務器進程在此空間運行
-
內核空間:操作系統內核運行的地方,負責系統級操作
首先MySQL
作為一個應用程序,運行在操作系統的用戶空間中,他并沒有直接訪問硬件設備的權限,這是現代操作系統的一個重要安全特性——內存保護機制;
當MySQL
需要讀取或寫入數據時,不能直接訪問磁盤,必須通過操作系統作為中介,由操作系統去訪問磁盤,因此三者之間的IO交互過程就是:MySQL——>系統——>磁盤。
IO交互流程詳解:
- 請求發起階段
MySQL需要讀取磁盤數據時,首先在用戶空間發起請求,通過系統調用進入內核空間;
- 權限切換
用戶態 → 內核態:系統調用觸發CPU模式切換;
權限提升:獲得直接訪問硬件和內核資源的權限;
- 內核處理階段
操作系統內核接收到請求后:
檢查文件系統緩存;
如果緩存未命中,向磁盤控制器發送I/O請求;
將數據從磁盤讀取到內核緩沖區(
4KB
頁大小);
- 數據傳遞階段
內核緩沖區 → MySQL緩沖區:將
4KB
的數據拷貝到用戶空間的MySQL緩沖區;數據整合:MySQL可能將
多個4KB頁
組合成16KB
的數據庫頁;
- 返回用戶態
系統調用完成,CPU重新切換回用戶態,MySQL繼續在用戶空間處理數據;
關鍵理解點:
空間隔離:
MySQL服務器和操作系統都在內存中運行;
但工作在不同的內存空間:用戶空間 vs 內核空間;
這種隔離確保了系統安全性和穩定性;
雙重IO概念:
- 系統與磁盤的IO交互:磁盤數據拷貝到內核緩沖區(4KB);
- MySQL與系統的IO交互:內核緩沖區數據拷貝到MySQL緩沖區(16KB);
2.為什么磁盤的最小讀寫單位是512字節的扇區,但系統卻選擇4KB作為IO操作的基本單位,這是因為:
- 如果操作系統直接使用硬件磁盤提供的數據大小進行交互,那么系統的IO代碼,就和硬件強相關,就好比,一旦硬件發生變化,系統也必須跟著變化;
- 除此之外,單次IO交互只有512字節,還是太小了;IO單位越小,意味著讀取同樣的數據內容,需要進行多次磁盤訪問,從會帶來IO效率上的降低;
- 并且之前學習的文件系統,就是在磁盤的基本結構下建立的,而文件系統的基本讀取單位就不是扇區512字節,而是數據塊4KB;
因此,系統和磁盤進行IO交互時,是以數據塊4KB為單位的。
3.為什么MySQL與系統這里IO操作的基本單位又是16KB,這是因為:
每次系統調用都涉及:
上下文切換:用戶態?內核態的CPU模式切換;
寄存器保存/恢復:需要保存當前進程狀態;
內存拷貝:數據在用戶空間和內核空間之間的傳輸;
調度開銷:可能涉及進程調度;
而MySQL
作為一款應用軟件,可以想象成一種特殊的文件系統,他有著更高的IO場景,所以,為了提高基本的IO效率,MySQL
的優化策略采用了批量處理原則:
減少系統調用次數:通過增加單次傳輸數據量來減少調用頻率;
4KB → 16KB:將多個系統頁合并成一個數據庫頁;
預讀機制:一次性讀取可能需要的連續數據;
MySQL
直接和系統進行IO交互的基本單位是16KB(后面統一使用InnoDB
存儲引擎講解),而不是系統的4KB;這也相當于MySQL
間接和磁盤進行數據交互的基本單位也是16KB;這個16KB基本數據單元,在MySQL
這里叫作page
,也可以叫做頁(注意不是系統的4KBpage
,兩者有區別的)。
這樣的優化策略,可以使原本的4次系統調用優化后變成只需要1-2次系統調用,大大減少了系統調用的開銷;
此外還能提高數據吞吐量:
更大的數據塊:每次傳輸更多有用數據;
更好的緩存命中率:16KB頁可能包含更多相關數據;
減少碎片化:減少小數據塊的隨機訪問;
4.最后總結:
MySQL
中的數據文件,是以page
(16KB頁)為單位保存在磁盤中的;MySQL
中表數據的增刪查改(CURD操作),都需要通過計算,找到對應的插入位置,或者找到對應的修改或者查詢的數據;- 而只要涉及到計算,就需要CPU的參與,需要先將數據從磁盤加載到內存中;
MySQL
服務器在內存中運行的時候,在服務器內部就申請了一個Buffer Poll
的大內存空間,來進行各種緩存。其實就是一個很大的用戶級緩沖區,來和磁盤數據進行IO交互;- 所以在特定的時間內,數據一定是在磁盤中有,內存中也有。后續操作完內存數據后,再以特定的刷新策略,將內存上的數據刷新到磁盤中,保證數據被修改 。而這時,就涉及到磁盤和內存的數據交互,也就是IO了,而此時IO的基本單位就是page;
- 為了更高的IO效率,就一定要盡可能地減少IO的次數;
二.索引的理解
1.Page頁模式
建立測試表
mysql> CREATE TABLE users(-> id int PRIMARY KEY,-> age int NOT NULL,-> name varchar(30) NOT NULL-> );
Query OK, 0 rows affected (0.42 sec)mysql> DESC users;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| age | int | NO | | NULL | |
| name | varchar(30) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.02 sec)
插入多條記錄
mysql> INSERT INTO users values-> (5, 20, '張三'),-> (3, 18, '李四'),-> (1, 19, '王五'),-> (2, 21, '趙六'),-> (4, 19, '陳七');
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
查看插入結果
mysql> SELECT * FROM users;
+----+-----+--------+
| id | age | name |
+----+-----+--------+
| 1 | 19 | 王五 |
| 2 | 21 | 趙六 |
| 3 | 18 | 李四 |
| 4 | 19 | 陳七 |
| 5 | 20 | 張三 |
+----+-----+--------+
5 rows in set (0.00 sec)
根據上面的結果,可以發現雖然插入時故意設置成無序的,但是查看結果時,顯示的確實有序的結果,這就是我們想要看到的一個現象。
那為什么變成有序的呢?這又是誰干的?這樣排序又有什么好處呢?
首先數據按照id
字段自動排序顯示,這是因為id
字段被定義為 PRIMARY KEY
(主鍵),MySQL會自動為主鍵創建聚集索引;
聚集索引特性:在InnoDB
存儲引擎中,表數據實際上是按照主鍵的順序物理存儲的;
所以當查看數據時,MySQL優化器會選擇使用主鍵索引來掃描數據,自然就按照主鍵順序返回結果;
因此變成有序是因為聚集索引的特性以及查詢優化,這個工作當然就是由MySQL數據庫存儲引擎自動完成的了。
至于這樣排序有什么好處,在回答這個問題之前先來回到另一個問題:
為什么MySQL與磁盤的IO交互采用Page模式,而不是用多少,加載多少的逐條加載模式?
如果是逐條加載模式:
查找id=1 → 加載1次
查找id=2 → 加載2次(需要先加載id=1)
查找id=5 → 加載5次(需要加載id=1,2,3,4,5)
而Page模式:
查找id=1 → 加載1個page(包含id=1,2,3,4,5)
查找id=2 → 從內存緩沖區獲取(無需IO)
查找id=5 → 從內存緩沖區獲取(無需IO)
在前面已經提到過:為了更高的IO效率,就需要減少IO交互的次數;
顯然采用逐條加載的方式,隨著數據越來越多,當要查詢較大的id值時,所需要的加載次數就會越來越大;而Page方式可以一次性加載多個數據(16KB大小),加載后保存在MySQL緩沖區中,即使部分數據本次用不到,但是可能在之后的查詢中就會用到,這時候就不需要重新和磁盤進行IO交互,而是直接從緩沖區中讀取即可,這樣就大大的減少了IO交互的次數;所以采用Page方式進行IO交互,而不是逐條加載的方式。
明白了這一點,再來看為什么需要進行排序?
排序的重要性:
- 局部性原理:相同的數據很可能被一起訪問;
- 預讀優化:MySQL可以預測性的加載后續頁面;
- 緩存命中率:有序數據更容易保持在內存中;
- 減少磁盤尋道:有序數據在磁盤中的扇區地址也是連續的,順序訪問減少磁頭移動
理解單個Page
一個表中如果有大量的數據,就需要大量的page進行存儲,也就是說內存中會存在大量的page;因此系統需要對這些page進行管理,管理方式就是先描述再組織,先描述:將page抽象成一個個的結構體,再組織:用數據結構將每個page組織起來;并且數據庫表本質上就是文件,所以一個獨立的文件是由一個或多個page組成的。
不同的Page
,在MySQL
中,都是16KB,使用prev
和next
構成雙向鏈表;因為有主鍵得存在,MySQL
會默認按照主鍵給我們的數據進行排序,從上面的Page
內數據記錄可以看出,數據是有序且彼此關聯的;
所以前面提到得存儲數據時要進行排序的好處,除了前面提到的幾點之外,還有一點就是:
Page
內部存放數據的模塊,本質上也是一個鏈表結構,鏈表的特點也就是增刪查改,查詢修改慢,所以優化查詢的效率是必須的;正是因為有序,在查找的時候,從頭到后都是有效的查找,沒有任何一個查找是浪費的,而且,如果運氣好,是可以提前結束查找過程的。
理解多個Page
在上面的頁模式中,只有一個功能,就是在查詢某條數據的時候直接將一整頁的數據加載到內存中,以減少硬盤IO次數,從而提高性能。但是,我們也可以看到,現在的頁模式內部,實際上是采用了鏈表的結構,前一條數據指向后一條數據,本質上還是通過數據的逐條比較來取出特定的數據;
那假如有1千萬條數據,就一定需要多個Page
來保存1千萬條數據,多個Page
彼此使用雙鏈表鏈接起來,而且每個Page
內部的數據也是基于鏈表的;那么,查找特定一條記錄,也一定是線性查找;這效率就會大大降低。
兩次鏈表遍歷:
-
頁間遍歷:從第一個Page開始,逐個遍歷Page鏈表,直到找到目標Page;
-
頁內遍歷:在目標Page內部,從第一條記錄開始,逐個遍歷記錄鏈表,直到找到目標數據;
為了解決數據量過大時,兩次鏈表遍歷帶來的效率低下問題,就需要引入一個新的概念頁目錄來解決;
2.頁目錄
先來理解一下什么是頁目錄?
想象一下你有一本很厚的書,比如《哈利波特》全集;這本書有幾千頁,如果你想快速找到某個特定的章節或內容,你會怎么做?
方法1:從頭開始一頁頁翻
- 這就像沒有索引的數據庫表,要找到某條記錄需要全表掃描;
方法2:使用目錄
-
書的前面有目錄,告訴你每個章節在第幾頁;
-
這就是頁目錄的作用!
單頁情況優化
頁內目錄管理:
-
一個數據頁內部包含頁目錄和數據記錄;
-
每個頁目錄項由:鍵值+指針構成;
-
這里的指針指向的是某行數據記錄的位置,也就是說頁內目錄管理的級別是行;
在一個Page
內部,引入頁目錄之后,當要查找id=4
的記錄,之前必須先行遍歷4次,才能拿到結果,現在直接通過頁目錄2[3]就可以定位到新的起始位置,然后開始線性遍歷,不用再從最起始位置開始遍歷,大大提高了效率;
這時候再來看前面的那個問題,為什么存儲數據時要進行排序?這里的頁目錄不就很好的體現出來優勢了。
單個Page內部的頁目錄優化:
-
原來:從Page內第一條記錄開始,逐個遍歷記錄鏈表;
-
現在:先在頁目錄中查找,找到最接近目標記錄的位置,然后從該位置開始遍歷;
-
效果:大大減少了Page內部的遍歷次數;
多頁情況優化
接下來就是解決數據頁之間的鏈表遍歷所帶來的效率問題,根據數據頁內部的解決方式,也可以給每個數據頁也帶上目錄:
頁間目錄管理:
- 一個目錄頁內部只包含頁目錄,不包含數據記錄;
- 每個頁目錄項由:鍵值+指針構成;
- 這里的指針指向的是某頁的位置,也就是說頁間目錄管理的級別是頁;
存在一個目錄頁來管理頁目錄,目錄頁中的鍵值指的是那一頁中最小的數據,通過鍵值數據的比較,找到目標頁,再根據指針到目標頁中查找目標數據;
目錄頁的本質也是頁,只不過數據頁中的數據是表中的行數據記錄,而目錄頁中的數據其實就是每個數據頁的指針;
但是,對于數據記錄量非常大的表,可能會出現頁目錄之間的鏈表也逐漸變長的情況,導致目錄頁之間的鏈表遍歷降低效率,這里就不用擔心了,根據頁目錄的思路,我們可以給每個目錄頁也添加頁目錄,形成多級索引結構,比如說一級頁目錄,二級頁目錄等等,逐步形成一個龐大的B+樹;
這正是MySQL B+樹索引的核心設計思想。
3.B樹 VS B+樹
B樹(B-Tree)結構
1.B樹的基本概念
B樹是一種自平衡的多路搜索樹,專門為磁盤存儲設計;
B樹的特點
B樹節點結構示例(m階B樹):
┌─────┬─────┬─────┬─────┬─────┐
│ P0 │ K1 │ P1 │ K2 │ P2 │
└─────┴─────┴─────┴─────┴─────┘其中:
- Ki:關鍵字(索引值)
- Pi:指向子節點的指針
- 每個節點最多有m個子節點
- 每個節點最少有?m/2?個子節點(根節點除外)
2.B樹的性質
- 所有葉子節點都在同一層;
- 葉子節點和非葉子節點都存儲索引和數據;
- 節點內關鍵字按升序排列;
- 滿足平衡性要求;
3.B樹查找過程
假設查找關鍵字K:
- 從根節點開始;
- 在當前節點中查找K;
- 如果找到,直接返回結果;
- 如果沒找到,根據K的大小選擇對應的子節點指針;
- 重復2,3,4步驟,直到找到或達到葉子節點;
B+樹(B+Tree)結構
1.B+樹的基本概念
B+樹是B樹的變種,是MySQL InnoDB存儲引擎使用的主要索引結構;
2.B+樹的結構特點
B+樹結構示例:根節點(非葉子)┌─────────┬─────────┬─────────┐│ 10 │ 20 │ 30 │└────┬────┴────┬────┴────┬────┘│ │ │┌────────┴──┐ ┌────┴────┐ ┌──┴────────┐│ 5 │ 8 │ │ 15 │ 18 │ │ 25 │ 35 │ 非葉子節點└──┬───┴─┬──┘ └─┬──┴─┬──┘ └─┬──┴──┬──┘│ │ │ │ │ │葉子節點層(存儲實際數據):┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐│ 3 │ 4 │→│ 5 │ 6 │→│ 8 │ 9 │→│15 │16 │→│18 │19 │→│25 │26 │└───┴───┘ └───┴───┘ └───┴───┘ └───┴───┘ └───┴───┘ └───┴───┘↑_______________________________________|(雙向鏈表)
- 節點結構差異
-- 非葉子節點(只存儲索引)
┌─────┬─────┬─────┬─────┬─────┐
│ P0 │ K1 │ P1 │ K2 │ P2 │ -- 只有索引值和指針
└─────┴─────┴─────┴─────┴─────┘-- 葉子節點(存儲完整數據)
┌─────┬─────┬─────┬─────┬─────┬─────┐
│ K1 │ Data│ K2 │ Data│ ... │Next │ -- 索引值+完整數據+鏈表指針
└─────┴─────┴─────┴─────┴─────┴─────┘
- 葉子節點鏈表結構
所有葉子節點通過雙向鏈表連接,支持高效的范圍查詢;
3.B樹 VS B+樹
- 數據存儲位置
B樹:
- 非葉子節點和葉子節點都存儲數據;
- 數據分散在整個樹中;
B+樹:
- 只有葉子節點存儲完整數據;
- 非葉子節點只存儲索引值;
- 查詢性能對比
等值查詢
- B樹:可能在任何層找到數據,查詢路徑不固定;
- B+樹:必須到葉子節點,查詢路徑固定,IO次數穩定;
范圍查詢
B樹:需要進行中序遍歷,效率較低;
B+樹:利用葉子節點鏈表,效率極高;
- 存儲空間利用率
B+樹優勢:
- 非葉子節點不存儲數據,可以存儲更多索引項;
- 相同的頁面大小可以有更高的扇出比(fanout);
- 樹的高度更低,查詢IO次數更少;
計算示例:
假設頁面大小16KB,索引項8字節,數據100字節:
- B樹:每個節點約存儲 16KB/(8+100)B ≈ 151個項;
- B+樹非葉子:每個節點約存儲 16KB/8B = 2048個項;
- 磁盤IO效率
B+樹在磁盤IO方面的優勢:
- 更低的樹高度 → 更少的磁盤訪問;
- 順序訪問友好 → 利用磁盤預讀;
- 更好的緩存局部性;
這就是為什么MySQL InnoDB
存儲引擎選擇B+樹作為索引結構的核心原因,它完美適配了數據庫系統對高效查詢、范圍搜索和磁盤IO優化的需求。
4.聚簇索引 VS 非聚簇索引
聚簇索引
1.基本概念
聚簇索引就是數據和索引存儲在一起的索引,索引的葉子節點直接存儲完整的行數據;
2.特點
聚簇索引結構:根節點/ | \內部節點 內部節點 內部節點/ | \ / | \ / | \[葉子][葉子][葉子][葉子][葉子][葉子]↓ ↓ ↓ ↓ ↓ ↓
完整行數據 完整行數據 完整行數據 完整行數據 完整行數據 完整行數據
- 一個表中只能有一個聚簇索引(通常是主鍵);
- 數據按照索引順序物理存儲;
- 查詢時通過聚簇索引找到葉子節點,直接返回整行數據;
非聚簇索引
1.基本概念
非聚簇索引是索引和數據分開存儲的,索引葉子節點存儲的是主鍵值。
2.特點
非聚簇索引結構:根節點/ | \內部節點 內部節點 內部節點/ | \ / | \ / | \[葉子][葉子][葉子][葉子][葉子][葉子]↓ ↓ ↓ ↓ ↓ ↓主鍵ID 主鍵ID 主鍵ID 主鍵ID 主鍵ID 主鍵ID↓ ↓ ↓ ↓ ↓ ↓通過主鍵再次查找聚簇索引獲取完整數據
- 一個表可以有多個非聚簇索引;
- 需要回表操作(先查索引,再查數據);
- 查詢時通過非聚簇索引找到葉子節點,獲取該記錄對應的主鍵ID值;
- 再通過主鍵id在聚簇索引中查找完整行數據;
簡單總結
聚簇索引:數據和索引在一起,查詢快但只能有一個,適用于主鍵查詢,范圍查詢,排序操作等場景;一次查找,直接獲取整行數據;
非聚簇索引:索引指向數據位置,需要回表但可以有多個,適用于多條件查詢,輔助查詢條件等場景;兩次查找,先獲取主鍵,再回表通過主鍵獲取整行數據;
在
MySQL InnoDB
中:
主鍵 = 聚簇索引
其他索引 = 非聚簇索引
三.索引的操作
創建索引
創建主鍵索引
- 第一種方式
-- 在創建表時,直接在字段名后指定主鍵索引
mysql> CREATE TABLE user1(-> id int PRIMARY KEY,-> name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.07 sec)
- 第二種方式
-- 在創建表的最后,指定某列或某幾列為主鍵索引
mysql> CREATE TABLE user2(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL,-> PRIMARY KEY(id)-> );
Query OK, 0 rows affected (0.06 sec)
- 第三種方式
mysql> CREATE TABLE user3(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.05 sec)-- 創建表以后添加主鍵索引
mysql> ALTER TABLE user3 add PRIMARY KEY(id);
Query OK, 0 rows affected (0.11 sec)
Records: 0 Duplicates: 0 Warnings: 0
主鍵索引的特點:
- 一個表中,最多有一個主鍵索引,當然可以是復合主鍵;
- 主鍵索引的效率高(主鍵不可重復)
- 創建主鍵索引的列,它的值不能為NULL,且不能重復;
- 主鍵索引的列基本上是int;
唯一鍵索引的創建
- 第一種方式
-- 在表定義時,在某列后直接指定unique唯一屬性。
mysql> CREATE TABLE user4(-> id int UNIQUE-> ,name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.07 sec)
- 第二種方式
-- 創建表時,在表的后面指定某列或某幾列為unique
mysql> CREATE TABLE user5(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL,-> UNIQUE(id)-> );
Query OK, 0 rows affected (0.05 sec)
- 第三種方式
mysql> CREATE TABLE user6(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.05 sec)
-- 創建表以后添加唯一鍵索引mysql> ALTER TABLE user6 add UNIQUE(id);
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
唯一鍵索引的特點:
- 一個表中,可以有多個唯一索引;
- 查詢效率高;
- 如果在某一列建立唯一索引,必須保證這列不能有重復數據;
- 如果一個唯一索引上指定not null,等價于主鍵索引;
普通索引的創建
- 第一種方式
-- 在表的定義最后,指定某列為索引
mysql> CREATE TABLE user7(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL,-> index(id)-> );
Query OK, 0 rows affected (0.06 sec)
- 第二種方式
mysql> CREATE TABLE user8(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.06 sec)
-- 創建表以后添加普通索引
mysql> ALTER TABLE user8 ADD INDEX(id);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
- 第三種方式
CREATE TABLE user9(id INT,name VARCHAR(30) NOT NULL,age INT NOT NULL);-- 指定索引名CREATE INDEX idx_id ON user9(id);-- 或ALTER TABLE user9 ADD INDEX idx_id(id);
普通索引的特點:
- 一個表中可以有多個普通索引,普通索引在實際開發中用的比較多;
- 如果某列需要創建索引,但是該列有重復的值,那么我們就應該使用普通索引;
查詢索引
- 第一種方式
SHOW KEYS FROM 表名
- 第二種方式
SHOW INDEX FROM 表名
- 第三種方式
DESC 表名
刪除索引
- 第一種方式
-- 刪除主鍵索引
ALTER TABLE 表名 DROP PRIMARY KEY;
- 第二種方式
-- 其他索引的刪除
ALTER TABLE 表名 DROP INDEX 索引名
- 第三種方式
DROP INDEX 索引名 ON 表名
ec)
Records: 0 Duplicates: 0 Warnings: 0
- 第三種方式```sql
CREATE TABLE user9(id INT,name VARCHAR(30) NOT NULL,age INT NOT NULL);-- 指定索引名CREATE INDEX idx_id ON user9(id);-- 或ALTER TABLE user9 ADD INDEX idx_id(id);
普通索引的特點:
- 一個表中可以有多個普通索引,普通索引在實際開發中用的比較多;
- 如果某列需要創建索引,但是該列有重復的值,那么我們就應該使用普通索引;
查詢索引
- 第一種方式
SHOW KEYS FROM 表名
- 第二種方式
SHOW INDEX FROM 表名
- 第三種方式
DESC 表名
刪除索引
- 第一種方式
-- 刪除主鍵索引
ALTER TABLE 表名 DROP PRIMARY KEY;
- 第二種方式
-- 其他索引的刪除
ALTER TABLE 表名 DROP INDEX 索引名
- 第三種方式
DROP INDEX 索引名 ON 表名
以上就是關于MySQL索引結構的講解,如果哪里有錯的話,可以在評論區指正,也歡迎大家一起討論學習,如果對你的學習有幫助的話,點點贊關注支持一下吧!!!