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

MySQL 分表後自增 ID 衝突解決方案:三大架構模式

     編輯:MySQL 綜合教學

分表後無法依賴單表自增 ID,需全局唯一 ID 生成策略。本文對比資料庫自增表、Redis 原子計數器、隊列預分配三大方案,分析高併發性能、可用性、業務靈活度,助您選型落地。

一、問題背景

分表將數據分散至多張表,各表自增 ID 獨立 → 全局 ID 衝突。MySQL 無 Sequence 物件,需自行實現全局 ID 生成器。

二、方案對比

方案 1:資料庫自增表 (單點寫入)

CREATE TABLE create_id (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
) ENGINE=MyISAM;  -- MyISAM 表鎖效能較 InnoDB 穩定

PHP 獲取 ID:

function get_AI_ID() {
    $this->db->query("INSERT INTO create_id (id) VALUES ('')");
    return $this->db->insert_id();
}

性能分析

  • InnoDB:innodb_autoinc_lock_mode 控制鎖行為
    • 0 (Traditional):每次表鎖
    • 1 (Consecutive, 預設):可預測行數用輕量鎖,否則表鎖
    • 2 (Interleaved):無鎖,最高併發,但 ID 可能不連續
  • MyISAM:始終表鎖,高併發下嚴重阻塞

結論:低併發可用,高併發成為瓶頸。

方案 2:Redis 原子計數器 (高性能)

function get_next_autoincrement($timeout = 60) {
    // 分布式鎖防止並發初始化
    if (!acquire_lock("serial:lock", $timeout)) return 0;
    
    $id = $redis->incr("serial");
    if ($id > 1) { release_lock(); return $id; }
    
    // 首次初始化:從 DB 讀取最大 ID
    $maxId = $db->query("SELECT MAX(id) FROM user_posts")->fetchColumn();
    $id = $maxId + 1;
    $redis->set("serial", $id);
    release_lock();
    return $id;
}

優點:極高吞吐、原子操作、支援集群。缺點:引入外部依賴、需處理持久化一致性。

方案 3:隊列預分配 (業務靈活)

class IDGenerator {
    private $redis;
    public function __construct() { $this->redis = new Redis(); $this->redis->connect('127.0.0.1', 6379); }
    
    // 批量注入 ID 池
    public function refill_pool($ids) {
        foreach ($ids as $id) $this->redis->lPush('id_pool', $id);
    }
    
    // 獲取 ID
    public function next_id() { return $this->redis->lPop('id_pool'); }
}

// 初始化:生成 20 個不重複隨機 ID
$ids = [];
while (count($ids) < 20) {
    $n = rand(1000, 4000);
    if (!in_array($n, $ids)) $ids[] = $n;
}
$gen = new IDGenerator();
$gen->refill_pool($ids);

優點:可預分配「靚號」、支援業務語義 ID、削峰填谷。缺點:需監控池水位、自動補充邏輯複雜。

三、選型建議

場景推薦方案核心理由
中小併發、簡單架構資料庫自增表 (InnoDB mode=2)零依賴、ACID 保證
高併發、微服務Redis 原子計數器 / Snowflake 演算法水平擴展、毫秒級吞吐
業務需語義 ID (靚號、分段)隊列預分配靈活控制 ID 分佈

四、進階:Snowflake 演算法 (分布式 ID 標準解)

64-bit 長整數:1bit 符號 | 41bit 時間戳 | 10bit 機器碼 | 12bit 序列號,單機每秒 409 萬 ID,無中心協調,適合大規模分布式系統。

根據業務規模與架構演進,選擇最適合的全局 ID 策略。

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