首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 獲取全局唯一值的多種實現方案

     編輯:MySQL 綜合教學

MySQL 獲取全局唯一值的多種實現方案

在分散式系統、分庫分表、跨資料庫遷移等場景下,需要能夠在全局範圍內唯一標識記錄的 ID。MySQL 原生 AUTO_INCREMENT 僅在單表內唯一,無法滿足全局唯一需求。本文系統梳理五大主流方案,並給出選型建議。

方案一:UUID / UUID_SHORT()

SELECT UUID();        -- 36 字元字串,含連字號,基於時間+MAC+隨機數
SELECT UUID_SHORT();  -- 64 位無符號整數,基於 server_id + 時間 + 序列,較短
  • 優點: 無需協調,生成效能高,幾乎不會衝突。
  • 缺點: UUID 佔用空間大(36 bytes vs 8 bytes BIGINT),非單調遞增導致 B+ 樹頁面分裂,寫入效能隨資料量增長而下降;UUID_SHORT() 需確保 server_id 全局唯一。

方案二:自增 ID + 步長/偏移量

-- 主庫 1
SET @@auto_increment_increment=2;
SET @@auto_increment_offset=1;  -- 產生 1,3,5,7...

-- 主庫 2
SET @@auto_increment_increment=2;
SET @@auto_increment_offset=2;  -- 產生 2,4,6,8...
  • 適用: 雙主/多主同步架構。
  • 缺點: 擴容困難(需重新規劃步長),ID 可預測,洩露業務增長資訊。

方案三:Snowflake 演算法(Twitter 開源,64 位 Long)

結構:1bit 符號位 | 41bit 毫秒時間戳 | 10bit 機器/節點 ID | 12bit 序列號

-- MySQL 函數實現範例 (需 5.7+ 支援)
CREATE FUNCTION snowflake_id() RETURNS BIGINT DETERMINISTIC
BEGIN
    DECLARE epoch BIGINT DEFAULT 1609459200000; -- 2021-01-01
    DECLARE node_id INT DEFAULT 1;              -- 需部署時分配唯一
    DECLARE seq INT DEFAULT 0;
    DECLARE last_ts BIGINT DEFAULT 0;
    -- 實際生產建議在應用層(Java/Go/PHP)實現,避免 DB 鎖競爭
    RETURN (UNIX_TIMESTAMP(NOW(3))*1000 - epoch) << 22 | node_id << 12 | seq;
END
  • 優點: 趨勢遞增(利於索引)、內嵌時間戳、無中心協調、每秒百萬級吞吐。
  • 缺點: 依賴時鐘同步(NTP),機器 ID 需運維分配,MySQL 函數實現有鎖競爭瓶頸。

方案四:資料庫號段模式(美團 Leaf、百度 UID Generator 思想)

  1. 建立號段表:CREATE TABLE id_segment (biz_tag VARCHAR(128), max_id BIGINT, step INT, version INT);
  2. 應用啟動時批次獲取:UPDATE id_segment SET max_id = max_id + step WHERE biz_tag = 'order' AND version = old_version;
  3. 本地記憶體發號,用完再取。
  • 優點: DB 壓力極低(秒級 QPS)、ID 趨勢遞增、支援業務標籤隔離、易於擴容。
  • 缺點: 需應用層維護狀態,單點故障可能導致號段浪費。

方案五:MySQL 8.0 原生 UUID_TO_BIN / BIN_TO_UUID

-- 儲存為 16 字節 BINARY(16),節省 50% 空間,索引效能優於 CHAR(36)
INSERT INTO t(id, data) VALUES (UUID_TO_BIN(UUID()), 'test');
SELECT BIN_TO_UUID(id) FROM t;
  • 優點: 官方原生支援,儲存緊湊,可配合 UUID_TO_BIN(UUID(), 1) 將時間位移至高位,改善索引局部性。
  • 需求: MySQL 8.0+。

選型決策矩陣

場景推薦方案核心理由
單體應用、單表、低併發AUTO_INCREMENT最簡單、整數索引最優
微服務、分庫分表、中等併發Snowflake (應用層)去中心化、趨勢遞增、含時間語義
高併發、多業務線、需運維友好號段模式DB 壓力最小、批次發號、易監控
異構系統整合、離線數據融合UUID / UUID_TO_BIN全球唯一、無協調、8.0 索引優化

最佳實踐建議: 核心交易鏈路優先使用「號段模式」或「應用層 Snowflake」;日誌/審計/非核心表可用 UUID_TO_BIN(UUID(), 1);嚴禁在高寫入表直接使用標準 UUID() 作為主鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved