V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
mocxe2vwww
V2EX  ›  问与答

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

  •  
  •   mocxe2vwww · Dec 11, 2018 · 6830 views
    This topic created in 2694 days ago, the information mentioned may be changed or developed.

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

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

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

    大家有啥好的思路没?

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

    uuid 转 int,截取后 8 位, 实验下
    innoink
        8
    innoink  
       Dec 11, 2018 via Android
    8 位是 1000w,这个量其实不小
    innoink
        9
    innoink  
       Dec 11, 2018 via Android
    @mocxe2vwww 截取能保证不重复么
    innoink
        10
    innoink  
       Dec 11, 2018 via Android
    如果不考虑完全随机

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

    这个实现起来是最快的,只需要几行代码…
    Zzdex
        16
    Zzdex  
       Dec 12, 2018 via iPhone
    提前生成吧 1000w 不是很多啊
    akira
        17
    akira  
       Dec 12, 2018
    这个要的应该是用户数字 id 吧,这个没必要和唯一主键挂钩啊.
    建议用户表还是用自增字段做唯一主键,另外创建一个表是 自增 id->user_id 映射关系表,提前填写好数据,这样创建新用户的时候,sql 里面直接写就好了.
    kernel
        18
    kernel  
       Dec 12, 2018   ❤️ 1
    看这情况这只是个个人小项目,你会有 1000 万用户吗? 10w 顶多了吧,提前生成 10w 就行了。真有 10w 用户了再生成下一批。
    700388
        19
    700388  
       Dec 12, 2018
    太简单了吧,直接随机生成 8 位数字,再匹配是否生成过,没有生成过,就完事,生成过,在生成一次匹配。
    adgad2
        20
    adgad2  
       Dec 12, 2018
    有同样的需求、、、用的 redis 的做法,提前生成好,然后取
    mocxe2vwww
        21
    mocxe2vwww  
    OP
       Dec 12, 2018
    @akira 你这方法感觉简单实用
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4008 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 10:22 · PVG 18:22 · LAX 03:22 · JFK 06:22
    ♥ Do have faith in what you're doing.