MySQL实现Sequence,获取数据便主键Id
简单实现:
#######################################
创建主键表:
CREATE TABLE `tb_sequence` (
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`current_value` bigint(20) UNSIGNED NOT NULL DEFAULT 1 COMMENT '起始Id' ,
`increment` int(11) NOT NULL DEFAULT 1 COMMENT '步长' ,
PRIMARY KEY (`name`)
)
ENGINE=MyISAM
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
CHECKSUM=0
ROW_FORMAT=Dynamic
DELAY_KEY_WRITE=0;
#######################################
创建currval函数:
delimiter //
CREATE DEFINER = `root`@`%` FUNCTION `currval`(seq_name VARCHAR(50))
RETURNS bigint(20)
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE value BIGINT;
SELECT current_value INTO value
FROM tb_sequence
WHERE upper(name) = upper(seq_name);
RETURN value;
END;
//
#######################################
创建nextval函数
delimiter //
CREATE DEFINER = `root`@`%` FUNCTION `nextval`(seq_name VARCHAR(50))
RETURNS int(11)
READS SQL DATA
DETERMINISTIC
BEGIN
UPDATE tb_sequence
SET current_value = current_value + increment
WHERE name = seq_name;
RETURN currval(seq_name);
END;
//
#######################################
调用方法
select nextval("test"); --test为主键表字段内容
#######################################
注意:
以上方法不适合用于多线程,多线程会产生重复ID,用排他锁的方式实现(效率较低)
delimiter //
CREATE DEFINER = `root`@`localhost` FUNCTION `nextval_safe`(`name` varchar(64))
RETURNS bigint(20)
BEGIN
declare current integer;
set current = 0;
select t.current_value into current from tb_sequence t where t.`name` = `name` for update;
update tb_sequence t set t.current_value = t.current_value + t.increment where t.`name` = `name`;
set current = current + 1;
return current;
end;
//
#######################################
调用方法
select nextval_safe("test"); --test为主键表字段内容
#######################################
备注:
delimiter //......// 为在navicat工具时候执行语句所需的字符