网上mysql生成Sequence的方法不少,最常见的方法是:
1,创建一张表用来保存序列值
CREATE TABLE `t_sequence` (
`sequence_name` varchar(64) CHARACTER SET utf8 NOT NULL COMMENT '序列名称',
`value` int(11) DEFAULT NULL COMMENT '当前值',
PRIMARY KEY (`sequence_name`)
)
2,创建一个函数用来得到序列号
CREATE DEFINER=`root`@`localhost` FUNCTION `nextval_safe`(sequence_name varchar(64)) RETURNS int(11)
BEGIN
declare current integer;
set current = 0;
select t.value into current from t_sequence t where t.sequence_name = sequence_name for update;
update t_sequence t set t.value = t.value + 1 where t.sequence_name = sequence_name ;
set current = current + 1;
return current;
end
在上述函数中用select ... for update 锁住要修改的数据行,保证在并发操作时不会产生重复的序列号。
其实通过使用临时变量,可以将以上的select ... for update语句与update 语句合二为一。
具体做法如下:
CREATE DEFINER=`root`@`localhost` FUNCTION `nextval_safe_1`(sequence_name varchar(64)) RETURNS int(11)
BEGIN
update t_sequence t set t.value = (@current:=t.value+1) where t.sequence_name = sequence_name ;
return @current;
end
也就是只用了一条update语句就可以实现取序列号的功能。
需要注意的是临时变量的用法,不能写成
update t_sequence t set @current:=t.value+1),t.value= @current: where t.sequence_name = sequence_name ;
这样会导致语法错误。
另外通过简单地测试,发现改进后的函数执行速度似乎和改进前差不多,但形式上更简洁。