使用sequence做爲多區域部署的id

序言

隨着業務量的增加和國際化的需求,多區域部署已經是屢見不鮮,若是各區域數據須要互通那數據庫id就要全局惟一,自建sequence做爲一種自增id就是爲了解決mysql多區域部署id衝突問題。mysql

優劣勢

優勢

  1. 和uuid相比較,sequence配置在數據庫中不依賴機器環境,且是有序的
  2. 和mysql自增id相比較,適用於多區域部署,能夠劃分id段且隨時可控

缺點

  1. 須要根據業務評估id段,並在後期須要時進行調整
  2. 單區域id增加過快時,id分配不平均,已分配的id段不可用會形成id浪費

劃分原則

  1. 推薦使用bigint,不要使用bigint unsigned,由於bigint unsigned超出了long和int64的範圍,不少軟件包會報錯
  2. bigint最大值爲9223372036854775807,爲方便擴展id劃分時不要一次性所有分配完,如中國0-10e,美國10e-20e,歐洲20e-30e,當新增區域或者某一區域id段使用完時再新增id段,如美國修改sequence起始爲30e

具體操做

  1. 檢查mysql 自定義函數功能是否開啓sql

    執行show variables like '%log_bin_trust_function_creators%'檢查是否開啓,如aws默認是沒開啓的須要修改數據庫配置,執行SET GLOBAL log_bin_trust_function_creators=1;打開該功能,如遇到權限問題修改原始配置數據庫

  2. 建立sequence表bash

    -- sequence表
    DROP TABLE IF EXISTS sequence;
    -- 建sequence表,指定seq列爲大整型,可支持:0(default)到9223372036854775807(0到2^63–1)。
    CREATE TABLE sequence (
    name            VARCHAR(50) NOT NULL,      -- 表名
    current_value   BIGINT NOT NULL DEFAULT 0, -- 當前值
    increment       INT NOT NULL DEFAULT 1,    -- 步長
    PRIMARY KEY (name)  -- 不容許重複seq的存在
    ) ENGINE=InnoDB;
    複製代碼
  3. 建立函數session

  • function獲取當前id
    -- DELIMITER的做用是修改分隔符,由於語句中包含有分號須要替換成其餘分隔符
    DELIMITER /
    DROP FUNCTION IF EXISTS currval /
    CREATE FUNCTION currval(seq_name VARCHAR(50))
    RETURNS BIGINT
    BEGIN
        DECLARE value BIGINT;
        SELECT current_value INTO value
        FROM sequence
        WHERE upper(name) = upper(seq_name); -- 大小寫不區分.
        RETURN value;
    END;
    /
    DELIMITER ;
    複製代碼
  • function獲取下一個id
    DELIMITER /
    DROP FUNCTION IF EXISTS nextval /
    CREATE FUNCTION nextval (seq_name VARCHAR(50))
    RETURNS BIGINT
    BEGIN
        DECLARE value BIGINT;
        UPDATE sequence
        SET current_value = current_value + increment
        WHERE upper(name) = upper(seq_name);
        RETURN currval(seq_name);
    END;
    /
    DELIMITER ;
    複製代碼
  1. 檢查函數是否建立成功
  • 刪除:drop function 自定義函數名
  • 顯示:show create function 自定義函數名
  • 查看:show function status
  • 修改:alert function
  1. sequence表添加表的初始值和步長,如添加session表,初始值設置爲1000,步長設置爲2 insert into `sequence`(`name`,`current_value`,`increment`) values('session',1000,2)
  2. 使用nextval函數執行session表插入語句,如 INSERT INTO `session`(`id`, `uid`, `sig`, `expired`) VALUES (nextval('session'),123,'1231',now())因爲nextval做爲函數執行,不論sql執行是否成功,sequence都會增加,這和mysql自增id自己是同樣的

結束語

使用sequence做爲mysql增加id惟一麻煩之處就在於要控制id段,若是id段劃分過小容易出現id衝突,劃分太大又容易出現新增區域id不足的問題,因此須要評估業務量,固然若是不在意id是否有序,使用snowflake生成uuid也是一種不錯的選擇。函數

相關文章
相關標籤/搜索