最近做了一个功能:注册时为用户生成一个前台展示用的id
id的规则:
- 5-11位
- 不能重复
- 老用户的id等于user表的主键user_id(老用户的账号范围在6000004-6671144之间)
- 新用户使用生成规则进行生成
- 生成的账号不能包含连续的三位相同数字
流程很简单:
- 拿到上次生成的展示id+1
- 验证是否在老用户的范围内[是将展示id直接设置为6671145]
- 验证现在的展示id是否是靓号[是处理展示id,然后从第二步重新开始]
- 验证现在的展示id是否在库里存在[是展示id+1,然后从第二步重新开始]
- 获得符合条件的展示id
- 记录本次生成的展示id,用于下次生成
我要详细说的是第三步中处理展示id
方案一:每次展示id+1
方案二:每次展示id+100
方案三:从高位开始找到连续的三位相同的数字最低位在展示id中所处的位置n,然后给展示id+10的(count(展示id)-n)次方
方案四:从低位开始找到连续的三位相同的数字中间位在展示id中所处的位置m,然后给展示id+10的(count(展示id)-m)次方
方案一和二因为碰撞的次数实在太多,直接淘汰。
方案三有时候会跳过太多的有效的展示id,方案四计算起来更麻烦。所以后两种方案在项目实施中可以根据具体情况选择
方案三实施:
首先使用正则表达式验证靓号时,可以得到第一次出现连续的三位相同数字aaa,然后找到aaa在show_id中出现的位置,低位的位置就找到了
方案四实施:
首先将展示id切割成数组(每一位都是数组的一个值),然后将数组倒序,循环数组,当找到连续三次相同数字时,跳出循环,得到key,m=key+1.
到这里我的减少碰撞的实施方案就完了。
当然有可能有考虑不周的地方。欢迎拍砖。