V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐工具
RoboMongo
推荐书目
50 Tips and Tricks for MongoDB Developers
Related Blogs
Snail in a Turtleneck
a719114136
V2EX  ›  MongoDB

借助 mongodb 生成自增 id 是否可行?

  •  
  •   a719114136 · 2019-07-15 18:23:29 +08:00 · 11681 次点击
    这是一个创建于 1956 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务需要生成一个自增 id,正好项目了用到 mogondb,用他的new ObjectId()来生成 id 就不启其他服务了。

    有人使用过这个方法吗,是否会带来性能问题?

    25 条回复    2019-07-16 16:13:59 +08:00
    glaucus
        1
    glaucus  
       2019-07-15 18:29:27 +08:00 via iPhone
    我目前就是这样,好像没发现啥性能问题,也有可能是我总能不高
    glaucus
        2
    glaucus  
       2019-07-15 18:30:14 +08:00 via iPhone
    @glaucus 总能-》并发
    VensonEEE
        3
    VensonEEE  
       2019-07-15 18:35:08 +08:00
    Snowflake,了解一下
    MartinWu
        4
    MartinWu  
       2019-07-15 18:40:24 +08:00
    他每一个文档必然有一个 objectid (官方建议),那就不需要显式生成。就更谈不上性能问题了吧。。
    rrfeng
        5
    rrfeng  
       2019-07-15 18:56:17 +08:00 via Android
    MongoDB ObjectID 并不保证自增!它自增是因为有时间戳,你在多线程里同时调用是没有严格顺序的。
    可以看下官方文档它的实现。
    honeycomb
        6
    honeycomb  
       2019-07-15 19:00:06 +08:00 via Android
    objectId 的算法公开的,也可以自己生成,也有现成的库
    a719114136
        7
    a719114136  
    OP
       2019-07-15 19:06:45 +08:00
    @MartinWu 这个 id 不是在 mongo 里用,是给其他服务用
    PHPJit
        8
    PHPJit  
       2019-07-15 19:06:57 +08:00 via Android
    redis 的 inc 也可以啊
    PHPJit
        9
    PHPJit  
       2019-07-15 19:07:30 +08:00 via Android
    incr
    a719114136
        10
    a719114136  
    OP
       2019-07-15 19:12:44 +08:00
    @PHPJit inc 要记录上次生成的数,不同表还要分别保存
    a719114136
        11
    a719114136  
    OP
       2019-07-15 19:13:43 +08:00
    @rrfeng 多谢提醒
    lands
        12
    lands  
       2019-07-15 20:06:25 +08:00
    redis 有个 Snowflake 的 module
    DovaKeen
        13
    DovaKeen  
       2019-07-15 20:40:11 +08:00
    ObjectId 的时间戳精确到秒,同一秒内生成的两个 ObjectId 好像先后顺序是无法确定的哦
    chendy
        14
    chendy  
       2019-07-15 20:56:53 +08:00
    junbaor
        15
    junbaor  
       2019-07-15 20:58:02 +08:00
    在公司大规模用过,没出问题,放心玩吧。
    SmartKeyerror
        16
    SmartKeyerror  
       2019-07-15 21:08:08 +08:00 via Android
    服务号+时间戳+redis.incr,如果有长度限制的话,incr 结果取模即可,小整数的服务号区分服务,线程安全且自增
    junbaor
        17
    junbaor  
       2019-07-15 21:11:44 +08:00   ❤️ 1
    我勒个去,自己测了一把,50 个线程生成 10 万个,有两三百个重复的,楼主慎重。
    petelin
        18
    petelin  
       2019-07-16 09:18:04 +08:00 via iPhone
    美团有篇文章讲怎么生成 还开源了一个 最好机器生成
    jifengg
        19
    jifengg  
       2019-07-16 10:32:13 +08:00
    同意 @PHPJit 说的,用单例的 redis 的 incr 来实现,“记录上次的数”,“不同表”都没有问题。
    FightForFreedom
        20
    FightForFreedom  
       2019-07-16 10:45:11 +08:00
    不是很懂为什么执着于自增 id,是和之前的老数据对接么
    a719114136
        21
    a719114136  
    OP
       2019-07-16 14:26:41 +08:00
    @FightForFreedom 1.自增对数据库建索引有帮助。2.可以用于分页
    JCZ2MkKb5S8ZX9pq
        22
    JCZ2MkKb5S8ZX9pq  
       2019-07-16 14:29:19 +08:00
    Before this discussion, recall that the BSON Object ID consists of:

    [4 bytes seconds since epoch, 3 bytes machine hash, 2 bytes process ID, 3 bytes counter]

    https://stackoverflow.com/questions/4677237/possibility-of-duplicate-mongo-objectids-being-generated-in-two-different-colle
    liuguang
        23
    liuguang  
       2019-07-16 15:52:17 +08:00
    object id 与时间戳、机器码、进程号、和随机数有关,一般而言,重复的概率极低,即使重复了也无关紧要,做好 unique 索引就不用担心了
    jziwenchen
        24
    jziwenchen  
       2019-07-16 16:04:04 +08:00
    担心重复的话 可以给每一个生成器加一个前缀吗 ...
    jk1030
        25
    jk1030  
       2019-07-16 16:13:59 +08:00
    @jifengg 单独 incr 不考虑 redis 异常情况? 如果断电是不是还要强制 aof 恢复?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3306 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 11:58 · PVG 19:58 · LAX 03:58 · JFK 06:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.