编辑
2021-08-11
undefined
00
请注意,本文编写于 1132 天前,最后修改于 28 天前,其中某些信息可能已经过时。

目录

需求

针对每一个用户(用户量在 10w 以下)随机生成的邀请码(仅限六位数字),且不重复

思考

如果能把这个不重复条件去除,那么只需要使用Math.random然后取小数点后六位就行了,但可惜要求就是不能重复, 要是重复还得了,到时候注册的时候都不知道奖励给那个邀请码账号。同时还要求邀请码在六位且数字,这就导致即使随机生成的,会有一定的可能出现相同的邀请码。

解决方案

方案 1

先随机生成一个六位随机数字,然后在存的时候判断数据库是否存在该邀请码,如果存在那么就重新生成一个,直到该邀请码不存在,便存入。

优点:方便,如果用户量不大,完全可以缺点:用户量上来的情况下,判断邀请码是否存在有可能需要一段时间,并且由于需要判断,故性能欠缺

方案 2

利用 redis 的 set 数据类型,先将所有的邀请码存入到 set 中,然后通过 srandmember 随机获取一个数值,在通过 srem 删除该元素即可。

或者也可以通过 list 队列,将预先随机生成的六位不重复数字的所有集合统统添加到队列中,然后获取的时候通过 rpop 或 lpop 获取

优点:相当于空间换时间,无需判断,后期即便用户量上来的,也完全可以重新生成一批(七位或字母)重新导入

缺点:过于依赖 Redis,redis 服务一旦停止,便无法正常获取数据。

实现

既然想都想了,那怎么能不实现呢。我这边仅仅是一个测试 Demo,利用的是方案 2,通过 set 数据类型进行获取相关代码如下

预先存入数据

js
let key = 'code' function genCode() { let num = 999999 for (let i = 100000; i < num; i++) { client.sadd(key, i, function (err, data) {}) } console.log('数据导入完毕') } genCode()

获取数据并删除

js
// 输出所有成员 client.smembers(key, function (err, data) { console.log(data) }) // 随机获取一个数据 client.srandmember(key, function (err, data) { console.log(data) client.srem(key, data, function (err, data) {}) })

通过console.time()获取数据耗时如下

default: 0.174ms

本文作者:任浪漫

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明出处!