背景
在做数据迁移的时候,数据没有主键,需要自动生成主键,且原有业务数据都是雪花算法生成的ID,为了兼容这种情况,实现方案如下。
MYSQL 的序列生成
- 定义序列
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 ;
- 设置序列的初始值
“myseq” 是序列名称,可以自定义。
“1987378867709424090”是UUID_SHORT()生成的(17位),去掉前俩位,加了“1987”,总共就是19位了,和雪花算法的长度一致,格式一致。另外雪花算法的前几位是时间戳,因为基本不会重复。
insert into sequence set name='myseq';
select setval('myseq',1987378867709424090);
- 验证效果
SELECT nextval('myseq'),zzid from f_s_wl_ys_sxjzcb_copy1;
nextval(‘myseq’) 放到你的insert语句中即可。