V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
mocxe2vwww
V2EX  ›  问与答

生成 8 位数字 作为用户的唯一主键, 如何保证唯一?

  •  
  •   mocxe2vwww · 2018-12-11 21:18:46 +08:00 · 5780 次点击
    这是一个创建于 1935 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目不考虑分布式, 但是上线之后,用户并发注册的情况会很大,而且要求不能用自增,数字不能包含 0

    时间成本有限,不能太复杂了,所以我想到最简单的方案: 每次直接程序内生成一个 8 位数,再去 user 表 for update 后找一下看有没有。

    还想到的一种方法:直接在 redis 队列中生成 100w 个均匀分布,每次 pop 一个

    大家有啥好的思路没?

    21 条回复    2018-12-12 14:39:02 +08:00
    herozhang
        1
    herozhang  
       2018-12-11 21:21:53 +08:00 via iPhone   ❤️ 2
    提前生成好,来一个激活一个
    xern
        2
    xern  
       2018-12-11 21:36:16 +08:00 via Android
    GUID 了解一下
    nightv2
        3
    nightv2  
       2018-12-11 21:50:55 +08:00 via Android
    @xern +1
    herozhang
        4
    herozhang  
       2018-12-11 22:28:04 +08:00
    @xern lz 说了只要 8 位数字
    bolide2005
        5
    bolide2005  
       2018-12-11 22:29:21 +08:00   ❤️ 1
    时间戳加随机数
    egen
        6
    egen  
       2018-12-11 22:32:16 +08:00
    redis 的方案吧,for update 还是慢
    mocxe2vwww
        7
    mocxe2vwww  
    OP
       2018-12-11 22:36:15 +08:00
    @xern 好吧,正好在看文档,https://docs.sqlalchemy.org/en/latest/core/custom_types.html

    uuid 转 int,截取后 8 位, 实验下
    innoink
        8
    innoink  
       2018-12-11 23:15:29 +08:00 via Android
    8 位是 1000w,这个量其实不小
    innoink
        9
    innoink  
       2018-12-11 23:17:21 +08:00 via Android
    @mocxe2vwww 截取能保证不重复么
    innoink
        10
    innoink  
       2018-12-11 23:20:53 +08:00 via Android
    如果不考虑完全随机

    可以每次拿一个区间,random shuffle 以后使用
    每次的区间不重叠就行了
    john1989
        11
    john1989  
       2018-12-11 23:28:16 +08:00 via Android
    线性同余法
    580a388da131
        12
    580a388da131  
       2018-12-11 23:41:15 +08:00 via iPhone
    排排队就好了,没必要弄那么复杂。
    短期注册量大也就大那一会而已。
    leavan
        13
    leavan  
       2018-12-11 23:44:10 +08:00
    平方探测
    xenme
        14
    xenme  
       2018-12-11 23:51:39 +08:00 via iPhone
    基于用户名是生成 hash,找找主流 hash 算法,改造下成 8 位就好。
    swulling
        15
    swulling  
       2018-12-12 00:10:59 +08:00 via iPhone
    看你的用户量了,不超过百万量级完全可以在 redis 里维护一个 id set,每次新用户注册随机生成一个,验证是否在 set 里,如果在重复生成即可。

    这个实现起来是最快的,只需要几行代码…
    Zzdex
        16
    Zzdex  
       2018-12-12 00:17:58 +08:00 via iPhone
    提前生成吧 1000w 不是很多啊
    akira
        17
    akira  
       2018-12-12 00:32:14 +08:00
    这个要的应该是用户数字 id 吧,这个没必要和唯一主键挂钩啊.
    建议用户表还是用自增字段做唯一主键,另外创建一个表是 自增 id->user_id 映射关系表,提前填写好数据,这样创建新用户的时候,sql 里面直接写就好了.
    kernel
        18
    kernel  
       2018-12-12 09:14:44 +08:00   ❤️ 1
    看这情况这只是个个人小项目,你会有 1000 万用户吗? 10w 顶多了吧,提前生成 10w 就行了。真有 10w 用户了再生成下一批。
    700388
        19
    700388  
       2018-12-12 10:04:39 +08:00
    太简单了吧,直接随机生成 8 位数字,再匹配是否生成过,没有生成过,就完事,生成过,在生成一次匹配。
    adgad2
        20
    adgad2  
       2018-12-12 10:24:19 +08:00
    有同样的需求、、、用的 redis 的做法,提前生成好,然后取
    mocxe2vwww
        21
    mocxe2vwww  
    OP
       2018-12-12 14:39:02 +08:00
    @akira 你这方法感觉简单实用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2780 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 15:04 · PVG 23:04 · LAX 08:04 · JFK 11:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.