最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL唯一索引和主鍵索引的區(qū)別有哪些(面試官常問(wèn))

 更新時(shí)間:2026年04月15日 08:55:06   作者:皮皮林551  
在數(shù)據(jù)庫(kù)設(shè)計(jì)中,索引的選擇與使用是優(yōu)化查詢性能的關(guān)鍵,下面這篇文章主要介紹了MySQL唯一索引和主鍵索引區(qū)別有哪些的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

面試考察點(diǎn)

  1. 索引類型理解:面試官不僅僅是想知道 "有什么區(qū)別",更是想考察你是否理解主鍵索引(聚簇索引)和唯一索引(二級(jí)索引)在存儲(chǔ)結(jié)構(gòu)上的根本差異。
  2. NULL 值處理:考察你是否清楚主鍵不允許 NULL,而唯一索引可以(但只能有一個(gè)),這是很多面試者容易忽略的細(xì)節(jié)。
  3. 性能優(yōu)化意識(shí):理解聚簇索引和非聚簇索引的查詢效率差異,能否在設(shè)計(jì)表結(jié)構(gòu)時(shí)做出正確選擇。

核心答案

主鍵索引:一種特殊的唯一索引,每張表只能有一個(gè),用于唯一標(biāo)識(shí)每一行記錄,InnoDB 中主鍵是 聚簇索引。

唯一索引:保證索引列的值唯一,一張表可以有多個(gè)唯一索引,InnoDB 中唯一索引是 二級(jí)索引(非聚簇索引) 。

核心區(qū)別對(duì)比

對(duì)比維度主鍵索引(PRIMARY)唯一索引(UNIQUE)
數(shù)量限制每表 只能有 1 個(gè)每表 可以有多個(gè)
NULL 值不允許 NULL允許 NULL(但最多 1 個(gè))
存儲(chǔ)結(jié)構(gòu)聚簇索引,葉子節(jié)點(diǎn)存完整數(shù)據(jù)二級(jí)索引,葉子節(jié)點(diǎn)存主鍵值
索引回表不需要回表需要回表(查詢非索引列時(shí))
創(chuàng)建語(yǔ)法PRIMARY KEY (col)UNIQUE KEY uk_name (col)
是否必須建議有,但不強(qiáng)制按需創(chuàng)建

一句話總結(jié):主鍵是 唯一的聚簇索引,不允許 NULL;唯一索引是 可以有多個(gè)的非聚簇索引,允許 NULL。

深度解析

一、存儲(chǔ)結(jié)構(gòu)差異:聚簇索引 vs 二級(jí)索引

主鍵索引和唯一索引在 InnoDB 中的存儲(chǔ)結(jié)構(gòu)完全不同:

上圖對(duì)比了主鍵索引和唯一索引的存儲(chǔ)結(jié)構(gòu)。關(guān)鍵區(qū)別在于:

  • 主鍵索引(聚簇索引) :葉子節(jié)點(diǎn)直接存儲(chǔ) 完整的行數(shù)據(jù),通過(guò)主鍵查詢可以直接獲取所有字段,無(wú)需回表
  • 唯一索引(二級(jí)索引) :葉子節(jié)點(diǎn)只存儲(chǔ) 索引列的值 + 主鍵值,如果查詢其他字段,需要拿著主鍵值回表查詢聚簇索引

二、NULL 值處理差異

這是面試中的高頻考點(diǎn):

-- 創(chuàng)建測(cè)試表
CREATETABLEuser (
    idBIGINT PRIMARY KEY,           -- 主鍵,不允許 NULL
    email VARCHAR(50) UNIQUE,        -- 唯一索引,允許 NULL
    phone VARCHAR(20) UNIQUE         -- 唯一索引,允許 NULL
);
-- 主鍵測(cè)試:插入 NULL 會(huì)報(bào)錯(cuò)
INSERTINTOuser (id, email) VALUES (NULL, 'test@qq.com');
-- ? ERROR 1048: Column 'id' cannot be null
-- 唯一索引測(cè)試:允許 NULL,且 MySQL 中可以插入多個(gè) NULL
INSERTINTOuser (id, email) VALUES (1, NULL);      -- ? 成功
INSERTINTOuser (id, email) VALUES (2, NULL);      -- ? 成功(MySQL 認(rèn)為多個(gè) NULL 不重復(fù))
INSERTINTOuser (id, email) VALUES (3, 'a@qq.com'); -- ? 成功
INSERTINTOuser (id, email) VALUES (4, 'a@qq.com'); -- ? Duplicate entry

關(guān)鍵結(jié)論

  • 主鍵:絕對(duì)不允許 NULL,這是主鍵的基本約束
  • 唯一索引:允許 NULL,且 MySQL 中可以插入多個(gè) NULL 值(因?yàn)?nbsp;NULL != NULL

三、查詢性能差異:回表問(wèn)題

通過(guò)主鍵查詢 vs 通過(guò)唯一索引查詢的性能差異:

-- 表結(jié)構(gòu)
CREATETABLEuser (
    idBIGINT PRIMARY KEY,
    email VARCHAR(50) UNIQUE,
    nameVARCHAR(50),
    age INT
);
-- 場(chǎng)景 1:通過(guò)主鍵查詢
SELECT * FROMuserWHEREid = 1;
-- ? 直接走聚簇索引,一次查詢即可獲取完整數(shù)據(jù)
-- 場(chǎng)景 2:通過(guò)唯一索引查詢所有字段
SELECT * FROMuserWHERE email = 'test@qq.com';
-- ?? 需要回表:先查唯一索引得到 id,再回表查聚簇索引
-- 場(chǎng)景 3:通過(guò)唯一索引查詢索引列(覆蓋索引)
SELECT email FROMuserWHERE email = 'test@qq.com';
-- ? 覆蓋索引,不需要回表

四、使用場(chǎng)景建議

場(chǎng)景推薦索引類型原因
標(biāo)識(shí)每一行記錄主鍵索引每表必須有唯一標(biāo)識(shí),推薦自增 BIGINT
用戶郵箱不能重復(fù)唯一索引業(yè)務(wù)唯一性約束,允許未設(shè)置郵箱(NULL)
手機(jī)號(hào)唯一唯一索引允許用戶暫未綁定手機(jī)號(hào)
身份證號(hào)唯一唯一索引允許 NULL(可能未錄入)
聯(lián)合唯一(用戶 + 日期)聯(lián)合唯一索引UNIQUE KEY uk_user_date (user_id, date)

最佳實(shí)踐

-- 推薦:使用 BIGINT 自增主鍵
CREATETABLE orders (
    idBIGINTUNSIGNED AUTO_INCREMENT PRIMARY KEY,
    order_no VARCHAR(32) UNIQUENOTNULL,  -- 業(yè)務(wù)訂單號(hào),不允許 NULL
    user_id BIGINTNOTNULL,
    INDEX idx_user (user_id)
);
-- 不推薦:沒(méi)有主鍵的表
-- MySQL 會(huì)自動(dòng)選擇一個(gè)非空唯一索引作為聚簇索引
-- 如果沒(méi)有合適的,會(huì)生成一個(gè)隱藏的 6 字節(jié)主鍵

五、如果沒(méi)有主鍵會(huì)怎樣?

InnoDB 要求每張表必須有聚簇索引:

面試高頻追問(wèn)

  1. 追問(wèn)一:為什么推薦使用自增主鍵而不是 UUID?
    • 答:自增主鍵是順序插入的,B+ 樹(shù)葉子節(jié)點(diǎn)順序追加,不會(huì)產(chǎn)生頁(yè)分裂;UUID 是無(wú)序的,插入會(huì)導(dǎo)致頻繁頁(yè)分裂,影響性能。此外,UUID 占用空間大(36 字符 vs 8 字節(jié)),降低索引效率。
  2. 追問(wèn)二:一張表可以沒(méi)有主鍵嗎?
    • 答:可以,但 InnoDB 會(huì)自動(dòng)選擇一個(gè)非空唯一索引作為聚簇索引;如果沒(méi)有合適的,會(huì)生成隱藏的 6 字節(jié) ROW_ID。但強(qiáng)烈不建議這樣做,應(yīng)該顯式定義主鍵。
  3. 追問(wèn)三:聯(lián)合主鍵和聯(lián)合唯一索引有什么區(qū)別?
    • 答:本質(zhì)區(qū)別和單列一樣——聯(lián)合主鍵是聚簇索引,不允許任何列為 NULL;聯(lián)合唯一索引是二級(jí)索引,允許列為 NULL。

常見(jiàn)面試變體

  • "主鍵索引和唯一索引有什么區(qū)別?"
  • "聚簇索引和非聚簇索引的區(qū)別是什么?"
  • "MySQL 查詢走唯一索引時(shí)為什么可能需要回表?"
  • "唯一索引允許 NULL 嗎?主鍵呢?"

記憶口訣

主鍵 vs 唯一索引

  1. 主鍵聚簇:葉子存完整數(shù)據(jù),查詢不回表
  2. 唯一二級(jí):葉子存主鍵值,查詢需回表
  3. NULL 有別:主鍵不允許,唯一索引可以
  4. 數(shù)量不同:主鍵唯一一個(gè),唯一索引多個(gè)

總結(jié)

主鍵索引是 聚簇索引,每表只能有一個(gè),不允許 NULL,葉子節(jié)點(diǎn)存儲(chǔ)完整行數(shù)據(jù);唯一索引是 二級(jí)索引,可以有多個(gè),允許 NULL(可多個(gè)),葉子節(jié)點(diǎn)存儲(chǔ)主鍵值。查詢時(shí)主鍵直接獲取數(shù)據(jù),唯一索引需要回表。推薦使用 BIGINT 自增主鍵,業(yè)務(wù)唯一約束用唯一索引。

到此這篇關(guān)于MySQL唯一索引和主鍵索引的區(qū)別有哪些的文章就介紹到這了,更多相關(guān)MySQL唯一索引和主鍵索引區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL數(shù)據(jù)庫(kù)觸發(fā)器從小白到精通

    MySQL數(shù)據(jù)庫(kù)觸發(fā)器從小白到精通

    觸發(fā)器是SQLserver提供給程序員和數(shù)據(jù)分析員來(lái)保證數(shù)據(jù)完整性的一種方法,它是與表事件相關(guān)的特殊的存儲(chǔ)過(guò)程,它的執(zhí)行不是由程序調(diào)用,也不是手工啟動(dòng),而是由事件來(lái)觸發(fā),比如當(dāng)對(duì)一個(gè)表進(jìn)行操作時(shí)就會(huì)激活它執(zhí)行。觸發(fā)器經(jīng)常用于加強(qiáng)數(shù)據(jù)的完整性約束和業(yè)務(wù)規(guī)則等
    2022-03-03
  • 淺談Mysql主鍵索引與非主鍵索引區(qū)別

    淺談Mysql主鍵索引與非主鍵索引區(qū)別

    本文主要介紹了ysql主鍵索引與非主鍵索引區(qū)別,文中介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • MYSQL 解鎖與鎖表介紹

    MYSQL 解鎖與鎖表介紹

    相對(duì)其他數(shù)據(jù)庫(kù)而言,MySQL的鎖機(jī)制比較簡(jiǎn)單,其最顯著的特點(diǎn)是不同的存儲(chǔ)引擎支持不同的鎖機(jī)制
    2017-04-04
  • MySQL字段自增自減的SQL語(yǔ)句示例介紹

    MySQL字段自增自減的SQL語(yǔ)句示例介紹

    MySQL的自增語(yǔ)句大家應(yīng)該都很熟悉,本文為大家介紹下MySQL字段自增自減的SQL語(yǔ)句,需要的朋友可以參考下
    2014-02-02
  • 解決mysql ERROR 1017:Can''t find file: ''/xxx.frm'' 錯(cuò)誤

    解決mysql ERROR 1017:Can''t find file: ''/xxx.frm'' 錯(cuò)誤

    如果重啟服務(wù)器前沒(méi)有關(guān)閉mysql,MySql的MyiSAM表很有可能會(huì)出現(xiàn) ERROR #1017 :Can't find file: '/xxx.frm' 的錯(cuò)誤
    2011-08-08
  • 一文詳解MySQL在Docker中的部署與數(shù)據(jù)持久化指南

    一文詳解MySQL在Docker中的部署與數(shù)據(jù)持久化指南

    這篇文章主要為大家詳細(xì)介紹了在Docker中運(yùn)行MySQL時(shí)確保數(shù)據(jù)持久化的關(guān)鍵方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2026-02-02
  • mysql?中的備份恢復(fù),分區(qū)分表,主從復(fù)制,讀寫分離

    mysql?中的備份恢復(fù),分區(qū)分表,主從復(fù)制,讀寫分離

    這篇文章主要介紹了mysql?中的備份恢復(fù),分區(qū)分表,主從復(fù)制,讀寫分離,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • MySQL的InnoDB引擎入門學(xué)習(xí)教程

    MySQL的InnoDB引擎入門學(xué)習(xí)教程

    這篇文章主要介紹了MySQL的InnoDB引擎入門學(xué)習(xí)教程,對(duì)InnoDB的存儲(chǔ)結(jié)構(gòu)有一個(gè)較好的總結(jié),需要的朋友可以參考下
    2015-11-11
  • MySQL WorkBench管理操作MySQL教程

    MySQL WorkBench管理操作MySQL教程

    MySQL Workbench提供DBAs和developers一個(gè)集成工具環(huán)境,方便管理mysql數(shù)據(jù)庫(kù),這里簡(jiǎn)單介紹下MySQL Workbench使用方法,需要的朋友可以參考下
    2014-03-03
  • mysql居然還能實(shí)現(xiàn)分布式鎖的方法

    mysql居然還能實(shí)現(xiàn)分布式鎖的方法

    這篇文章主要介紹了mysql居然還能實(shí)現(xiàn)分布式鎖的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01

最新評(píng)論

西盟| 阿巴嘎旗| 乐东| 财经| 乐陵市| 大足县| 太康县| 石首市| 新绛县| 淮安市| 万年县| 贺州市| 大渡口区| 河西区| 会泽县| 蒲江县| 正蓝旗| 兰州市| 邯郸县| 临安市| 塘沽区| 宿州市| 青阳县| 安福县| 临夏市| 公安县| 大方县| 怀柔区| 陵川县| 昌平区| 黄龙县| 池州市| 玛曲县| 大洼县| 兴国县| 赤城县| 吉隆县| 日照市| 兰溪市| 奉贤区| 鄂州市|