背景

在做数据迁移的时候,数据没有主键,需要自动生成主键,且原有业务数据都是雪花算法生成的ID,为了兼容这种情况,实现方案如下。

MYSQL 的序列生成

  1. 定义序列
DROP TABLE IF EXISTS sequence; 
 
-- 建sequence表,指定seq列为无符号大整型,可支持无符号值:0(default)到18446744073709551615(0到2^64–1)。
CREATE TABLE sequence (
   name       VARCHAR(50) NOT NULL, 
     current_value   BIGINT UNSIGNED NOT NULL DEFAULT 0, 
     increment     INT NOT NULL DEFAULT 1, 
     PRIMARY KEY (name)  -- 不允许重复seq的存在。
) ENGINE=InnoDB; 

set global log_bin_trust_function_creators=1;

 
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 ; 
 
 
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 ; 
 
DELIMITER /
 
DROP FUNCTION IF EXISTS setval / 
 
CREATE FUNCTION setval (seq_name VARCHAR(50), value BIGINT) 
RETURNS BIGINT
BEGIN 
     UPDATE sequence 
     SET current_value = value 
     WHERE upper(name) = upper(seq_name); 
     RETURN currval(seq_name); 
END;
/
 
DELIMITER ;
  1. 设置序列的初始值
    “myseq” 是序列名称,可以自定义。
    “1987378867709424090”是UUID_SHORT()生成的(17位),去掉前俩位,加了“1987”,总共就是19位了,和雪花算法的长度一致,格式一致。另外雪花算法的前几位是时间戳,因为基本不会重复。
insert into sequence set name='myseq';
select setval('myseq',1987378867709424090);
  1. 验证效果
SELECT nextval('myseq'),zzid from f_s_wl_ys_sxjzcb_copy1;

在这里插入图片描述

nextval(‘myseq’) 放到你的insert语句中即可。

更多推荐