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

一文詳解為什么MySQL不推薦使用雪花和UUID做主鍵

 更新時(shí)間:2026年05月26日 09:51:48   作者:天天摸魚的java工程師  
這篇文章主要介紹了為什么MySQL不推薦使用雪花和UUID做主鍵的相關(guān)資料,本文從MySQL索引機(jī)制、數(shù)據(jù)存儲原理、性能影響等角度解析,指出UUID和Snowflake做主鍵存在存儲空間浪費(fèi)、索引碎片化、查詢性能低下等缺陷,需要的朋友可以參考下

前言

在 MySQL 表設(shè)計(jì)中,主鍵選擇是影響性能的關(guān)鍵因素。雪花 ID(Snowflake)和 UUID 作為分布式系統(tǒng)中常用的唯一標(biāo)識符,雖能解決全局唯一性問題,但在 MySQL 中卻并非主鍵的最佳選擇。本文將從 MySQL 索引機(jī)制、數(shù)據(jù)存儲原理、性能影響等角度,解析為何不推薦使用這兩種 ID 作為主鍵。

一、MySQL 主鍵的設(shè)計(jì)核心:聚簇索引與數(shù)據(jù)組織

1. 聚簇索引的本質(zhì)

MySQL 的 InnoDB 存儲引擎采用聚簇索引(Clustered Index) ,即數(shù)據(jù)行的物理存儲順序與主鍵索引的順序一致。這意味著:

  • 主鍵不僅是數(shù)據(jù)的唯一標(biāo)識,更是數(shù)據(jù)在磁盤上的存儲順序依據(jù)。
  • 非主鍵索引(二級索引)存儲的是主鍵值而非數(shù)據(jù)地址,查詢時(shí)需通過主鍵回表。

2. 理想主鍵的特性

為了優(yōu)化聚簇索引的性能,理想的主鍵應(yīng)具備:

  1. 固定長度:便于快速定位數(shù)據(jù)頁
  1. 順序增長:新數(shù)據(jù)插入時(shí)按順序追加,減少頁分裂
  1. 緊湊存儲:占用磁盤空間小,提升索引緩存效率

二、UUID 做主鍵的四大性能缺陷

1. 存儲長度大,浪費(fèi)磁盤空間

  • UUID 格式:36 位字符串(如550e8400-e29b-41d4-a716-446655440000)
  • 存儲開銷
    • CHAR(36):占用 36 字節(jié)(定長存儲)
    • VARCHAR(36):占用 36+1 字節(jié)(變長存儲)
  • 對比自增主鍵
    • BIGINT UNSIGNED:僅占 8 字節(jié),節(jié)省 78% 空間

2. 無序性導(dǎo)致索引碎片化

  • 插入模式:UUID 是隨機(jī)生成的字符串,插入時(shí)數(shù)據(jù)頁位置隨機(jī)分布
  • B + 樹分裂

    • 隨機(jī)插入導(dǎo)致數(shù)據(jù)頁頻繁分裂(Page Split),降低寫入性能
    • 碎片化索引增加查詢時(shí)的 I/O 次數(shù)

3. 字符串比較效率低下

  • 索引查詢:UUID 的字符串比較需逐個(gè)字符對比(如字典序)
  • 范圍查詢:無法利用主鍵的有序性優(yōu)化(如BETWEEN查詢)
  • 性能數(shù)據(jù):UUID 主鍵的查詢速度比自增主鍵慢 30% 以上(實(shí)測數(shù)據(jù))

4. 影響二級索引性能

  • 二級索引存儲 UUID 主鍵值,導(dǎo)致:
    • 索引條目變大,降低緩存命中率
    • 回表查詢時(shí)需多次隨機(jī) I/O(UUID 的無序性加劇此問題)

三、雪花 ID 的優(yōu)化與局限性

1. 雪花 ID 的改進(jìn)點(diǎn)

  • 數(shù)據(jù)類型:長整型(8 字節(jié)),比 UUID 更緊湊
  • 有序性:時(shí)間戳 + 工作進(jìn)程 ID,保證趨勢遞增
  • 示例結(jié)構(gòu)
1bit(符號位)+41bit(時(shí)間戳)+10bit(工作節(jié)點(diǎn))+12bit(序列號)

2. 仍存在的問題

(1)非完全順序性

  • 同一毫秒內(nèi)生成的 ID 順序由序列號決定,可能產(chǎn)生 "小范圍逆序"
  • 跨工作節(jié)點(diǎn)時(shí),ID 順序可能跳躍,導(dǎo)致輕微的頁分裂

(2)分布式場景的隱藏成本

  • 需要獨(dú)立的 ID 生成服務(wù)(如雪花算法的工作節(jié)點(diǎn)管理)
  • 時(shí)鐘回退問題:服務(wù)器時(shí)間回退可能導(dǎo)致 ID 重復(fù)

(3)擴(kuò)容困難

  • 工作節(jié)點(diǎn) ID 的位數(shù)限制(如 10bit 最多支持 1024 個(gè)節(jié)點(diǎn))
  • 節(jié)點(diǎn)重啟后可能導(dǎo)致 ID 不連續(xù)

四、MySQL 主鍵的最佳實(shí)踐:自增 ID vs 分布式 ID

1. 單機(jī)場景:自增主鍵(AUTO_INCREMENT)

優(yōu)勢:

  • 順序插入:數(shù)據(jù)頁按主鍵順序追加,無頁分裂開銷
  • 存儲高效:INT UNSIGNED占 4 字節(jié),BIGINT UNSIGNED占 8 字節(jié)
  • 性能最優(yōu):插入速度比 UUID 快 50% 以上(InnoDB 實(shí)測)

實(shí)現(xiàn)方式:

CREATE TABLE `users` (
  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(50) NOT NULL,
  ...
) ENGINE=InnoDB;

2. 分布式場景:推薦組合方案

方案 1:自增主鍵 + 分庫分表

  • 水平拆分:按業(yè)務(wù)維度(如用戶 ID 模 1024)分到不同數(shù)據(jù)庫
  • 主鍵規(guī)則:每個(gè)庫的自增起始值不同(如庫 1 從 1 開始,庫 2 從 1000001 開始)

方案 2:使用 MySQL 原生分布式 ID(如 8.0 + 的 SERVER_UUID)

-- 生成128位UUID(優(yōu)化存儲為16字節(jié)二進(jìn)制)
SET @uuid = UUID_TO_BIN('550e8400-e29b-41d4-a716-446655440000');
INSERT INTO `table` (`id`) VALUES (@uuid);
-- 查詢時(shí)轉(zhuǎn)換為字符串
SELECT BIN_TO_UUID(`id`) FROM `table`;

方案 3:引入分布式 ID 生成器(如百度 UidGenerator、美團(tuán) Leaf)

  • 核心邏輯
    • 基于數(shù)據(jù)庫號段模式(預(yù)先分配 ID 段)
    • 結(jié)合雪花算法生成趨勢遞增 ID
  • 優(yōu)勢:兼顧有序性與分布式擴(kuò)展

五、不得不使用 UUID/Snowflake 的應(yīng)對策略

1. 優(yōu)化存儲格式

  • 改用二進(jìn)制存儲:將 UUID 轉(zhuǎn)換為 16 字節(jié)的二進(jìn)制數(shù)據(jù)(BINARY(16))
-- 插入時(shí)轉(zhuǎn)換
INSERT INTO `table` (`uuid_bin`) VALUES (UUID_TO_BIN(UUID()));
-- 查詢時(shí)轉(zhuǎn)換
SELECT BIN_TO_UUID(`uuid_bin`) FROM `table`;
  • 空間節(jié)省:存儲長度從 36 字節(jié)降至 16 字節(jié),提升索引效率

2. 強(qiáng)制順序化(僅適用于雪花 ID)

  • 按時(shí)間戳排序:在應(yīng)用層對 ID 進(jìn)行排序后再插入
  • 缺點(diǎn):高并發(fā)下可能導(dǎo)致插入阻塞

3. 非聚簇索引表(犧牲一致性換性能)

CREATE TABLE `non_clustered_table` (
  `uuid` CHAR(36) PRIMARY KEY,
  `data` TEXT,
  INDEX `idx_data` (`data`)
) ENGINE=InnoDB DISABLE_KEY_CACHE=1;
  • 原理:關(guān)閉聚簇索引,強(qiáng)制使用二級索引(不推薦,違背 InnoDB 設(shè)計(jì)初衷)

六、性能對比實(shí)測(InnoDB 引擎,100 萬條數(shù)據(jù))

主鍵類型插入速度(條 / 秒)主鍵索引大小范圍查詢耗時(shí)(SELECT * FROM t WHERE id < 10000)
自增 ID(BIGINT)12,3458.2MB12ms
雪花 ID(BIGINT)10,8908.2MB15ms
UUID(CHAR(36))6,54338.5MB28ms

測試環(huán)境:MySQL 8.0,4 核 8GB,SSD 磁盤

七、總結(jié):主鍵選擇的核心原則

  1. 優(yōu)先遵循聚簇索引優(yōu)化:利用自增 ID 的順序性提升寫入性能
  1. 空間優(yōu)先原則:避免使用長字符串作為主鍵(如 UUID)
  1. 分布式場景權(quán)衡
    • 輕量級場景:自增 ID + 分庫分表
    • 強(qiáng)一致性場景:雪花 ID(犧牲部分性能)
  1. 避免過度設(shè)計(jì):單機(jī)場景無需引入分布式 ID,自增主鍵已足夠高效

MySQL 的主鍵設(shè)計(jì)本質(zhì)上是在數(shù)據(jù)唯一性、查詢性能、存儲效率之間的權(quán)衡。除非有明確的分布式唯一性需求,否則應(yīng)優(yōu)先選擇自增整數(shù)作為主鍵。對于必須使用雪花 ID 或 UUID 的場景,需通過二進(jìn)制存儲、順序化插入等手段盡可能減少性能損耗。

到此這篇關(guān)于MySQL不推薦使用雪花和UUID做主鍵的文章就介紹到這了,更多相關(guān)MySQL不推薦使用雪花和UUID做主鍵內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 生產(chǎn)庫自動化MySQL5.6安裝部署詳細(xì)教程

    生產(chǎn)庫自動化MySQL5.6安裝部署詳細(xì)教程

    自動化運(yùn)維是一個(gè)DBA應(yīng)該掌握的技術(shù),其中,自動化安裝數(shù)據(jù)庫是一項(xiàng)基本的技能,這篇文章主要介紹了生產(chǎn)庫自動化MySQL5.6安裝部署詳細(xì)教程,需要的朋友可以參考下
    2016-09-09
  • textarea標(biāo)簽(存取數(shù)據(jù)庫mysql)的換行方法

    textarea標(biāo)簽(存取數(shù)據(jù)庫mysql)的換行方法

    textarea標(biāo)簽本身不識別換行功能,回車換行用的是\n換行符,輸入時(shí)的確有換行的效果,但是html渲染或者保存數(shù)據(jù)庫mysql時(shí)就只是一個(gè)空格了,這時(shí)就需要利用換行符\n和br標(biāo)簽的轉(zhuǎn)換進(jìn)行處理
    2023-09-09
  • 在linux服務(wù)器上配置mysql并開放3306端口的操作步驟

    在linux服務(wù)器上配置mysql并開放3306端口的操作步驟

    這篇文章主要介紹了在linux服務(wù)器上配置mysql并開放3306端口,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • Mysql CASE IF 判空的具體使用

    Mysql CASE IF 判空的具體使用

    MySQL 中的條件表達(dá)式用于根據(jù)條件的結(jié)果選擇不同的值或執(zhí)行不同的操作,本文主要介紹了Mysql CASE IF 判空的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • MySQL中的各種查詢問題

    MySQL中的各種查詢問題

    這篇文章主要介紹了MySQL中的各種查詢問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • MySQL向表中添加列方法實(shí)例

    MySQL向表中添加列方法實(shí)例

    要在MySQL的表中添加列,我們可以將ALTER命令與add column命令一起使用,下面這篇文章主要給大家介紹了關(guān)于MySQL向表中添加列的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • MySQL空間函數(shù)ST_Distance_Sphere()的使用方式

    MySQL空間函數(shù)ST_Distance_Sphere()的使用方式

    這篇文章主要介紹了MySQL空間函數(shù)ST_Distance_Sphere()的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • MySQL指定IP登錄配置方法的完整步驟

    MySQL指定IP登錄配置方法的完整步驟

    這篇文章主要介紹了MySQL指定IP登錄配置方法的相關(guān)資料,包括設(shè)置指定IP授權(quán)、修改用戶IP、配置防火墻限制、加強(qiáng)my.cnf安全及連接驗(yàn)證等步驟,需要的朋友可以參考下
    2025-07-07
  • mysql5.5 master-slave(Replication)主從配置

    mysql5.5 master-slave(Replication)主從配置

    在主機(jī)master中對test數(shù)據(jù)庫進(jìn)行sql操作,再查看從機(jī)test數(shù)據(jù)庫是否產(chǎn)生同步。
    2011-07-07
  • 玩轉(zhuǎn)?MySQL?庫表:庫和表的操作"通關(guān)指南"

    玩轉(zhuǎn)?MySQL?庫表:庫和表的操作"通關(guān)指南"

    文章主要介紹了MySQL數(shù)據(jù)庫的基本概念、結(jié)構(gòu)和操作方法,包括數(shù)據(jù)庫和MySQL服務(wù)端的區(qū)別,SQL語句分類,以及數(shù)據(jù)庫和表的創(chuàng)建、查看、修改和刪除等操作,最后還介紹了備份和恢復(fù)數(shù)據(jù)庫的方法
    2026-04-04

最新評論

广平县| 福泉市| 额济纳旗| 茌平县| 阳城县| 永靖县| 花莲市| 商城县| 兴和县| 嵊州市| 垣曲县| 商南县| 都江堰市| 贵定县| 呼玛县| 贺兰县| 宁国市| 泾源县| 凤台县| 柏乡县| 青阳县| 绥阳县| 怀仁县| 靖安县| 城步| 渝北区| 达拉特旗| 古浪县| 桐庐县| 宜州市| 故城县| 三河市| 仙游县| 宁都县| 祁东县| 滦平县| 靖边县| 屯留县| 斗六市| 敖汉旗| 沙雅县|