首先说一下设计思路,最终目的是生成一个时间+六位自增流水,实例:20180524000001.
具体实现过程简述:
1.创建两个数据库:
mr_invest_id14,投资id-内存表,用于存储新生成且未使用的流水号;
tb_invest_id14,投资id-物理表,用于存储已经使用过了的流水号;
2.流水号每天从当天年月日+000000 ~ 当天年月日+999999;
a. 每批次生成500个,存放到内存表,使用一个内存表就会删除相应的流水号,并将其存放到物理表留痕;
b.当内存表中的剩余未使用流水号<=50时,再依次生成500个流水号存放到内存表中,
所生成新流水号与上一批次最后一个流水号是连续的;
实现代码如下:
CREATE TABLE `mr_invest_id14` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`seq_date` varchar(63) DEFAULT NULL COMMENT 'Serial日期',
`seq_number` bigint(20) NOT NULL COMMENT '数值型10进制序列号',
`seq_code` varchar(63) DEFAULT '' COMMENT '返回的SeqNo值',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`use_flag` tinyint(1) DEFAULT '0' COMMENT '使用状态:false:未使用;true:已使用',
PRIMARY KEY (`id`),
KEY `IDX_UseFlag` (`use_flag`) USING BTREE,
KEY `IDX_SeqDate` (`seq_date`) USING BTREE
) ENGINE=MEMORY AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='投资id-内存表';
CREATE TABLE `tb_invest_id14` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`seq_date` varchar(63) DEFAULT NULL COMMENT 'Serial日期',
`seq_number` bigint(20) NOT NULL COMMENT '数值型10进制序列号',
`seq_code` varchar(63) DEFAULT '' COMMENT '返回的SeqNo值',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`use_flag` tinyint(1) DEFAULT '0' COMMENT '使用状态:false:未使用;true:已使用',
`use_time` datetime DEFAULT NULL COMMENT '使用时间',
PRIMARY KEY (`id`),
KEY `IDX_UseFlag` (`use_flag`) USING BTREE,
KEY `IDX_SeqDate` (`seq_date`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='投资id-物理表';
DROP FUNCTION IF EXISTS `getInvestId`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` FUNCTION `getInvestId`() RETURNS varchar(16) CHARSET utf8
COMMENT '生成投资id'
BEGIN
DECLARE resultNo varchar(16) DEFAULT '';
DECLARE resultSerialId bigint(20) default 0;
DECLARE currDateTime datetime DEFAULT NOW();
DECLARE serialDate varchar(16) DEFAULT DATE_FORMAT(currDateTime,'%Y%m%d');
DECLARE lastSeqNumber bigint(20) default 0;
DECLARE unUseSerialTotal int(11) default 0;
DELETE FROM `mr_invest_id14` where `seq_date` < serialDate ;
select count(1) into unUseSerialTotal from `mr_invest_id14` where `seq_date`=serialDate and `use_flag`=0 ;
if (unUseSerialTotal <= 50) then
select `seq_number` into lastSeqNumber from `mr_invest_id14` where `seq_date`=serialDate order by seq_number desc limit 1 ;
if(lastSeqNumber <= 0) then
select `seq_number` into lastSeqNumber from `tb_invest_id14` where `seq_date`=serialDate order by seq_number desc limit 1 ;
end if ;
if(lastSeqNumber <= 0) then
set lastSeqNumber = 0;
end if;
set @insertNumber=500;
set @inum=0;
while @inum < @insertNumber do
set @insertSerialNumber=lastSeqNumber + @inum + 1;
set @serialCode=LPAD(@insertSerialNumber,6,'0');
insert into `mr_invest_id14`(`seq_date`,`seq_number`,`seq_code`,`create_time`,`use_flag`)
values (serialDate,@insertSerialNumber,@serialCode,now(),0);
set @inum = @inum + 1;
end while;
end if;
select `id`,concat(serialDate,`seq_code`) into resultSerialId,resultNo from `mr_invest_id14` where `seq_date`=serialDate and `use_flag` = 0 order by `seq_number` asc limit 1;
insert into `tb_invest_id14`(`seq_date`,`seq_number`,`seq_code`,`create_time`,`use_flag`,`use_time`)
select `seq_date`,`seq_number`,concat(serialDate,`seq_code`),`create_time`,1,NOW() from `mr_invest_id14` where `id`=resultSerialId;
delete from `mr_invest_id14` where `id`=resultSerialId;
return resultNo;
END
;;
DELIMITER ;
结果演示: