MySQL的一級索引和二級索引的區(qū)別及說明
更新時間:2025年07月05日 09:19:12 作者:快點好好學習吧
這篇文章主要介紹了MySQL的一級索引和二級索引的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
第一部分:MySQL 的一級索引和二級索引的區(qū)別是什么?
一級索引和二級索引就像玩具工廠里的“清單”
生活中的例子:
- 想象一下,你在一家玩具工廠工作。工廠里有一個工人(相當于 MySQL)負責組裝玩具:
一級索引:
- 工人有一份完整的零件清單(相當于主鍵索引),上面記錄了每個零件的編號和具體位置。
- 這份清單是唯一的,每個零件編號只能對應一個位置。
二級索引:
- 工人還有一份分類清單(相當于非主鍵索引),上面記錄了零件的類別(如顏色、形狀)和對應的編號。
- 這份清單不是唯一的,一個類別可能對應多個零件編號。
在編程里:
- 一級索引(主鍵索引) 是基于主鍵構建的索引,直接指向主表中的完整數(shù)據(jù)。
- 二級索引(非主鍵索引) 是基于非主鍵列構建的索引,存儲的是主鍵值,需要回表才能獲取完整數(shù)據(jù)。
第二部分:包含哪些部分?
主要組成部分
一級索引(主鍵索引)
- 存儲主鍵值和指向主表數(shù)據(jù)的指針。
二級索引(非主鍵索引)
- 存儲非主鍵列的值和對應的主鍵值。
B+ 樹結構
- 一級索引和二級索引都使用 B+ 樹存儲數(shù)據(jù)。
查詢請求
- 用戶通過 SQL 查詢請求數(shù)據(jù)。
回表操作
- 當使用二級索引時,如果查詢字段不在索引中,需要回表查找完整數(shù)據(jù)。
第三部分:背后到底做了哪些事情?
核心思想
一級索引:
- 直接定位到主表中的完整數(shù)據(jù)。
二級索引:
- 先通過索引找到主鍵值,再通過主鍵值回到主表查找完整數(shù)據(jù)。
優(yōu)化策略:
- 盡量避免回表,例如使用覆蓋索引。
底層實現(xiàn)
B+ 樹索引:
- 一級索引和二級索引都使用 B+ 樹存儲數(shù)據(jù)。
葉子節(jié)點:
- 一級索引的葉子節(jié)點存儲主鍵值和完整數(shù)據(jù)。
- 二級索引的葉子節(jié)點存儲非主鍵列的值和主鍵值。
查詢計劃:
- MySQL 的查詢優(yōu)化器會決定使用哪種索引。
第四部分:示例代碼與詳細講解
示例代碼:模擬一級索引和二級索引的工作過程
<?php // 第一步:定義一個表 class Table { private $primaryKeyIndex; // 一級索引(主鍵索引) private $secondaryIndex; // 二級索引(非主鍵索引) private $mainTable; // 主表 public function __construct() { // 初始化一級索引(主鍵索引) $this->primaryKeyIndex = [ 1 => ['id' => 1, 'name' => 'Alice', 'age' => 25, 'city' => 'New York'], 2 => ['id' => 2, 'name' => 'Bob', 'age' => 30, 'city' => 'San Francisco'], 3 => ['id' => 3, 'name' => 'Charlie', 'age' => 35, 'city' => 'Los Angeles'] ]; // 初始化二級索引(非主鍵索引) $this->secondaryIndex = [ 'Alice' => ['id' => 1], 'Bob' => ['id' => 2], 'Charlie' => ['id' => 3] ]; // 初始化主表 $this->mainTable = [ 1 => ['id' => 1, 'name' => 'Alice', 'age' => 25, 'city' => 'New York'], 2 => ['id' => 2, 'name' => 'Bob', 'age' => 30, 'city' => 'San Francisco'], 3 => ['id' => 3, 'name' => 'Charlie', 'age' => 35, 'city' => 'Los Angeles'] ]; } // 使用一級索引查找數(shù)據(jù) public function queryWithPrimaryKey($id) { echo "正在通過一級索引查找記錄...\n"; // 查找一級索引 if (isset($this->primaryKeyIndex[$id])) { $record = $this->primaryKeyIndex[$id]; echo "一級索引中找到完整記錄:ID={$record['id']}, Name={$record['name']}, Age={$record['age']}, City={$record['city']}。\n"; } else { echo "未找到記錄。\n"; } } // 使用二級索引查找數(shù)據(jù) public function queryWithSecondaryIndex($name) { echo "正在通過二級索引查找記錄...\n"; // 查找二級索引 if (isset($this->secondaryIndex[$name])) { $indexRecord = $this->secondaryIndex[$name]; echo "二級索引中找到主鍵值:ID={$indexRecord['id']}。\n"; // 回表查找完整數(shù)據(jù) $mainRecord = $this->mainTable[$indexRecord['id']]; echo "回表后找到完整記錄:ID={$mainRecord['id']}, Name={$mainRecord['name']}, Age={$mainRecord['age']}, City={$mainRecord['city']}。\n"; } else { echo "未找到記錄。\n"; } } } // 第二步:模擬一級索引和二級索引的工作過程 $table = new Table(); echo "\n=== 模擬一級索引查詢 ===\n"; // 使用一級索引查詢 ID=2 的記錄 $table->queryWithPrimaryKey(2); echo "\n=== 模擬二級索引查詢 ===\n"; // 使用二級索引查詢 Name='Alice' 的記錄 $table->queryWithSecondaryIndex('Alice');
為什么要這樣寫?
- 第一步:定義一個
Table
類,模擬一級索引和二級索引的功能。 - 第二步:總結一級索引和二級索引的核心區(qū)別,展示其本質(zhì)。
背后發(fā)生了什么?
一級索引查詢:
- 直接通過主鍵定位到完整數(shù)據(jù)。
二級索引查詢:
- 先通過索引找到主鍵值,再回到主表查找完整數(shù)據(jù)。
結果返回:
- 返回完整的查詢結果。
總結核心作用:
- 展示一級索引和二級索引如何協(xié)作完成查詢。
第五部分:使用場景
一級索引
- 當查詢條件是主鍵時,使用一級索引。
- 例如:
SELECT * FROM users WHERE id=2;
二級索引
- 當查詢條件是非主鍵列時,使用二級索引。
- 例如:
SELECT * FROM users WHERE name='Alice';
數(shù)據(jù)完整性需求
- 當需要返回完整數(shù)據(jù)時,二級索引可能需要回表。
- 例如:查詢用戶的所有信息。
第六部分:底層原理
B+ 樹索引
一級索引:
- 葉子節(jié)點存儲主鍵值和完整數(shù)據(jù)。
二級索引:
- 葉子節(jié)點存儲非主鍵列的值和主鍵值。
回表操作
二級索引:
- 如果查詢字段不在索引中,需要回到主表查找完整數(shù)據(jù)。
查詢優(yōu)化
覆蓋索引:
- 如果查詢字段都在索引中,可以避免回表。
索引設計:
- 合理設計索引,減少回表次數(shù)。
第七部分:圖表與示意圖
思維導圖
MySQL 索引 ├── 一級索引 │ ├── 主鍵索引 │ └── 完整數(shù)據(jù) ├── 二級索引 │ ├── 非主鍵索引 │ └── 回表操作 └── 查詢優(yōu)化 ├── 覆蓋索引 └── 索引設計
流程圖
[查詢請求] --> [一級索引] --> [完整數(shù)據(jù)] [查詢請求] --> [二級索引] --> [回表操作] --> [完整數(shù)據(jù)]
架構圖
[一級索引] -----> [主表] -----> [完整數(shù)據(jù)] [二級索引] -----> [主表] -----> [完整數(shù)據(jù)]
類圖
+-------------------+ | Table | +-------------------+ | - primaryKeyIndex: array| | - secondaryIndex: array | | - mainTable: array | +-------------------+ | + queryWithPrimaryKey(): void| | + queryWithSecondaryIndex(): void| +-------------------+
序列圖
主程序 -> 表: 查詢請求 表 -> 一級索引: 查找記錄 一級索引 -> 表: 返回完整記錄 表 -> 主程序: 返回查詢結果 主程序 -> 表: 查詢請求 表 -> 二級索引: 查找記錄 二級索引 -> 表: 返回主鍵值 表 -> 主表: 回表查找 主表 -> 表: 返回完整記錄 表 -> 主程序: 返回查詢結果
數(shù)據(jù)流圖
[查詢請求] -----> [一級索引] -----> [完整數(shù)據(jù)] [查詢請求] -----> [二級索引] -----> [主表] -----> [完整數(shù)據(jù)]
示意圖
[一級索引] -----> [主表] -----> [完整數(shù)據(jù)] [二級索引] -----> [主表] -----> [完整數(shù)據(jù)]
第八部分:總結
一級索引和二級索引的本質(zhì)
一級索引:
- 基于主鍵構建,直接指向主表中的完整數(shù)據(jù)。
二級索引:
- 基于非主鍵列構建,存儲主鍵值,需要回表查找完整數(shù)據(jù)。
優(yōu)化策略:
- 盡量避免回表,例如使用覆蓋索引。
生活中的類比
一級索引和二級索引就像玩具工廠里的“清單”:
- 一級索引是完整的零件清單,直接找到零件。
- 二級索引是分類清單,先找到零件編號,再根據(jù)編號找到零件。
最后
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
MySQL數(shù)據(jù)庫case?when?then?end的詳細使用方法
在SQL語法中我們首先使用CASE關鍵字開頭,然后根據(jù)不同的條件使用WHEN關鍵字,并在每個條件后面指定結果,這篇文章主要給大家介紹了關于MySQL數(shù)據(jù)庫case?when?then?end的詳細使用方法,需要的朋友可以參考下2023-12-12