优惠券短链接批量生成工具:https://www.aifabu.com(免费、快速、安全带绿标)
电商系统一般需要用到优惠券或者兑换码之类的东西,比如:京东电子卡的卡密就是这么长,DJZ3-0PLF-C0E8-L0UF
京东电子卡是实体卡。如果卡密被定期跟踪,会带来惨痛的损失,所以它的生成算法应该是完全随机的。
我们知道大多数语言都支持生成随机整数的方式,并且不能保证100%的唯一性,所以我们不得不接受这个事实。
假设我们可以随机生成不重复的整数,那么如何将其转化为上面“字母+数字”的混合字符串形式呢?答案是:36 的补码。 36的补数的表达区间为0-9,A-Z(a-z),刚好满足要求。
所以我的方法是用一个随机函数生成长整形并转换成36的补码,但是一个长整形的36补码的宽度不够,所以我形成了两条36进制的随机数条纹, 并取回 .
一段PHP代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
函数 gen_coupon() {
做{
$m = mt_rand(0, PHP_INT_MAX);
$n = mt_rand(0, PHP_INT_MAX);
$m = base_convert($m, 10, 36);// 主随机数
$n = base_convert($n, 10, 36);// 二次随机
$r = substr($m . $n, 0, 16);
} while(strlen($r) != 16);
$r = strtoupper($r);
$r = str_split($r, 4);
$r = implode('-', $r);
返回 $r;
}
冲突率可以有多高?我已经生成了5000万个优惠券代码,重复了20个,没问题。
接下来的问题是,如何将这批优惠券代码保存到数据库中?因为不能防止重复,但是冲突率低的很惨,你不能去数据库5000万次查询20条冲突数据吧?
如果批量插入不好,那么重复的优惠券代码将由于唯一索引错误而中止,我该怎么办?解决方案也足够暴力。插入语句使用 on duplicate key 更新语法。当遇到唯一索引冲突时,可以进行无意义的更新更新:
1
在重复密钥更新 `code`='xxxx-xxxx-xxxx-xxxx' 时插入优惠券(`code`)值('xxxx-xxxx-xxxx-xxxx');
这样可以直接使用mysql客户端批量导出,也可以使用脚本程序批量导出数据库。
获取优惠券短链接
从数据库中随机获取一张优惠券并不容易。当多个程序同时查询数据库获取优惠券时,每个人都会收到同一张优惠券。显然,锁定数据库是不合理的。
我分享一个低成本的方案:优惠券可以保存在redis set结构中,可以保证key的唯一性,并且支持spop命令随机返回和删除一个key。最终的优惠券领取流程应该是一个执行步骤,从redis set获取优惠券code,然后到mysql中作为自己的。