方法一
来自网络搜索
思路: 创建一个触发器,在执行insert之前,查询id中数字部分最大的数,并拼接新id
优点: 无需额外自增id占用内存
缺点: 性能开销大,数据量越来越大,插入效率越来越低
-- 创建数据表
CREATE TABLE `tbl_school` (
`id` char(12) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL,
`is_delete` tinyint(1) DEFAULT 0 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学校信息表';
-- 创建触发器
CREATE TRIGGER tbl_school_insert
BEFORE INSERT ON tbl_school
FOR EACH ROW
SET NEW.id = CONCAT(
'school_',
LPAD(
(SELECT IFNULL(MAX(SUBSTR(id, 8)) + 1, 1) FROM tbl_school),
5,
'0'
)
);
方法二
由方法一改良
思路: MAX(SUBSTR(id, 8))
操作非常消耗算力,如果新增一列自增长主键auto_id
,直接取最大的auto_id
进行拼接,算力会小很多,且耗时固定
优点: 性能开销最低,查询时间稳定,表中原本就设计有自增长键非常合适
缺点: 需要额外新增一列,逼死强迫症
-- 创建数据表
CREATE TABLE `tbl_school` (
`auto_id` INT AUTO_INCREMENT NOT NULL,
`id` char(12) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL,
`is_delete` tinyint(1) DEFAULT 0 NOT NULL,
PRIMARY KEY (`auto_id`)
) ENGINE=InnoDB COMMENT='学校信息表';
-- 创建触发器
CREATE TRIGGER tbl_school_insert
BEFORE INSERT ON tbl_school
FOR EACH ROW
SET NEW.id = CONCAT(
'school_',
LPAD(
(SELECT IFNULL(MAX(auto_id) + 1, 1) FROM tbl_school),
5,
'0'
)
);
方法三
由方法一、方法二延伸
思路: 方法一的时间主要消耗在,每次查询拼接的数字时,都会把表中所有id
进行截取之后取max,如果直接按id
倒序取第一条的id,即当前的最大id进行截取后取数,会少很多的字符串截取排序的查询性能消耗。
优点: 无需额外自增id占用内存,性能开销很低,查询时间稳定
缺点: 时间相较于方法二略高一点,但取舍之下性价比最高
-- 创建数据表
CREATE TABLE `tbl_school` (
`id` char(12) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL,
`is_delete` tinyint(1) DEFAULT 0 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学校信息表';
-- 创建触发器
CREATE TRIGGER tbl_school_insert
BEFORE INSERT ON tbl_school
FOR EACH ROW
SET NEW.id = CONCAT(
'school_',
LPAD(
(SELECT IFNULL( (SELECT (SUBSTR(id, 8) + 1) FROM tbl_school ORDER BY id DESC LIMIT 1) , 1)),
5,
'0'
)
);
性能对照测试
批量插入数据sql参照: https://blog.lakesideknight.com/archives/176
方法一:插入第1-1000条数据,耗时2.78秒
…
本示例可能不是最优解,若有更好的实现方法请在评论区分享给大家。
评论