蜘蛛网有很多购物卡,电影优惠券,抵用券。
比如一个需求后台此刻需要生成新的一批10万条卡号,3万给微信渠道,5万主站,app,2万外部渠道发放。
那么如何快速生成卡号,而且不重复呢?
逻辑很简单,就是通过某种方法生成一个随机的卡号,然后去数据库排重,不重复就插入,直到10万条。
1、什么方法生成卡号呢?
不同的业务类型可以区分,抵用券的用DY开头,兑换券用DH开头,这样做是为了查询重复时候加速,你还可以继续加维度
2、怎么生成,保证速度?
一开始只想到怎么生成卡号数据,能避免查询重复,结果卡的长度不太可能短,体验不好。
后来经同事一提醒,存储过程,那就写存储过程。
存储过程结果也是比较慢,1000条大约33s。然后又问那个同事,批量。我想起来mysql的批量
set autocommit=0;
CREATE TABLE `biz_card` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cardno` varchar(50) DEFAULT NULL,
`status` tinyint(4) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `ix_cardno` (`cardno`)
) ENGINE=InnoDB AUTO_INCREMENT=7303 DEFAULT CHARSET=utf8;
DROP PROCEDURE IF EXISTS `genCardNo`;
CREATE PROCEDURE genCardNo(IN num int)
begin
-- 产生一个随机7位数
DECLARE newCard int;
set autocommit=0;
while num>0 do
SET newCard=FLOOR(10000000+ (RAND() * 89999999));
select @repCount:=count(id) from biz_card where cardno=CONCAT('DY',newCard);
-- 重复判断
if @repCount>0 THEN
SELECT concat('the value is repeat:', 'DY',newCard);
else
insert biz_card(cardno,status)values(CONCAT('DY',newCard),0);
set num = num - 1;
if num%5000=0 then
SELECT concat('begin commit,num:',num);
commit;
end if;
end if;
end WHILE;
commit;
end;
[SQL] call genCardNo(1000);
受影响的行: 1
时间: 0.3s
[SQL] call genCardNo(100000);
受影响的行: 0
时间: 15.350s
这样好像可以了。如果数据量再大呢,接下来我的想法是通过消息队列分发到不同机器上去生成,排重采用redis存储处理