环境
MyBatis-Plus
MySQL 5.7
前言
最近因业务需要,需要在一张主键非自增的表里使用 SQL 插入数据,表结构如下:
CREATE TABLE non_inc
(
id BIGINT NOT NULL
PRIMARY KEY
-- 其他字段
);
原 id 生成策略是 MyBatis-Plus IdType::ASSIGN_ID
,此时 SQL 插入数据时若不提供主键将会报错,提供的主键需要满足以下条件:
- 不能修改原来的表结构
- 数字类型
- 唯一且不能和未来的 id 冲突
解决方案
根据需求与约束我打开了 MySQL 的文档 Mathematical Functions 查找有关数字的函数,查看了一轮貌似可以根据 RAND() 和 ROUND() 相组合完成 id 的生成,但是会有一个致命的弱点,生成的随机数字有可能冲突,想到这里直接放弃该方案。
要是能能添加 AUTO INC
约束就好了,我不经这么想着,既然不能添加约束,那我模拟生成不就行了?想到这马上开干,实现步骤为:
- 若是第一步,生成一个不会和历史与未来冲突的 id
- 若不是第一步,获取上一个 id + 1 当作当前 id
查阅文档 LAST_INSERT_ID() 能很好的解决我的问题,于是乎就得到了下面 SQL:
INSERT INTO non_inc(id)
SELECT IF(LAST_INSERT_ID() = 0,
LAST_INSERT_ID(NOW() * 1000),
LAST_INSERT_ID(LAST_INSERT_ID() + 1));