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

php 订单号方案,重复的可能性要很低很低很低,大家说说自己的方案。

  •  
  •   444683462 · 2014-10-26 18:23:52 +08:00 · 6038 次点击
    这是一个创建于 3688 天前的主题,其中的信息可能已经有所发展或是发生改变。
    php订单号方案,重复的可能性要很低很低很低,大家说说自己的方案。
    44 条回复    2014-11-02 18:00:23 +08:00
    abelyao
        1
    abelyao  
       2014-10-26 18:53:00 +08:00
    有长度要求吗?有排序要求吗?纯数字还说可英文?并发量估计会去到多少?
    bystand3r
        2
    bystand3r  
       2014-10-26 19:14:58 +08:00
    同楼上……你的格式要求呢……给你来个1024位的?
    sy1989
        3
    sy1989  
       2014-10-26 19:37:29 +08:00
    mysql 的自增好了
    arslion
        4
    arslion  
       2014-10-26 19:40:32 +08:00
    @sy1989 +1
    vibbow
        5
    vibbow  
       2014-10-26 19:47:15 +08:00
    用 UUID
    imn1
        6
    imn1  
       2014-10-26 19:47:15 +08:00
    类别+时间+随机数
    yylzcom
        7
    yylzcom  
       2014-10-26 19:51:01 +08:00
    timestamp+userid(+random number)
    xiaoyaoking
        8
    xiaoyaoking  
       2014-10-26 19:54:34 +08:00
    7 楼正解, 其实 timestamp 就不会重复了。。 想要长度就 timestamp md5 妥妥的。
    orvice
        9
    orvice  
       2014-10-26 19:57:45 +08:00
    时间(精确到秒)+随机数基本就可以了吧
    spance
        10
    spance  
       2014-10-26 20:00:11 +08:00
    PHP很难做到。

    不要为了一个没有前景的语言徒劳奔命。更何况,php还不能算是一个完整的语言。

    首先,语言层面就没有线程、锁、信号量、原子CAS等等这些很基本的东西,更缺乏体系规范,php5开始搞伪伪伪面向对象,学不像更鸡肋,还有那么多对C函数的简单包装。。。

    除了最近本CRUD外,稍微复杂的业务逻辑or业务系统是没法用php实现的。除了搞搞简单页面输出,真看不出这玩意还有啥难能可贵的地方。

    不要在本就不长的人生路上浪费时间。
    polythene
        11
    polythene  
       2014-10-26 20:02:58 +08:00
    @spance 啊!!PHP才是世界上最好的语言,嘿嘿。
    barbery
        12
    barbery  
       2014-10-26 20:13:11 +08:00
    mysql主键自增 或者redis counter
    aveline
        13
    aveline  
       2014-10-26 20:24:34 +08:00
    uniqid()
    lch21
        14
    lch21  
       2014-10-26 21:37:43 +08:00
    uniqid() +1
    xoxo
        15
    xoxo  
       2014-10-26 21:40:20 +08:00
    md5( auto_increament_id + salt );
    anewg
        16
    anewg  
       2014-10-26 21:41:09 +08:00   ❤️ 3
    @spance 你也是挺逗的,人家来求解决业务需求,你来给人家人生忠告。一个 uniqid() 就解决的事,难不成让他跟老板说“没有信号量、原子CAS很难做到,不要在本就不长的人生路上浪费时间,老板我们换个语言不?”
    xoxo
        17
    xoxo  
       2014-10-26 21:42:14 +08:00
    @xoxo by the way, https://sslcertificate.cn的系统就是采用 md5( auto_increament_id + salt ) 的方式,其它既然不能猜到使用量,也不防止了碰撞
    spance
        18
    spance  
       2014-10-26 21:52:47 +08:00
    @anewg
    有的时候领悟领悟人生忠告比研究研究某方法要来的透彻来的深刻。
    用php玩高并发玩金融相关,结果是怎么死的你都不知道。
    当然,玩玩什么wordpress之类小玩意是没有问题的。
    laotaitai
        19
    laotaitai  
       2014-10-26 22:03:57 +08:00
    @spance
    半吊子水才说得出这样的话.
    curiousjude
        20
    curiousjude  
       2014-10-26 22:05:22 +08:00   ❤️ 2
    @spance 那你倒是说说解决方案啊。你这种答案说得好听叫没有帮助,说得不好听叫制造噪音。
    zts1993
        21
    zts1993  
       2014-10-26 22:16:41 +08:00
    /**
    * 生成UUID
    * @return string
    */
    function gen_uuid()
    {
    if (function_exists('com_create_guid')) {
    return com_create_guid();
    } else {
    mt_srand((double)microtime() * 10000); //optional for php 4.2.0 and up.
    $char_id = strtoupper(md5(uniqid(rand(), true)));
    $hyphen = chr(45); // "-"
    $uuid = chr(123) // "{"
    . substr($char_id, 0, 8) . $hyphen
    . substr($char_id, 8, 4) . $hyphen
    . substr($char_id, 12, 4) . $hyphen
    . substr($char_id, 16, 4) . $hyphen
    . substr($char_id, 20, 12)
    . chr(125);
    // "}"
    return $uuid;
    }
    }
    young
        22
    young  
       2014-10-26 22:24:11 +08:00 via iPhone
    我是用日期+当天的秒数、毫秒+随机数来的,一般小站差不多
    PS:人家是来寻找答案的,怎么某些人就喜欢吓j8BB呢,不得瑟能死吗?
    imydou
        23
    imydou  
       2014-10-26 22:29:17 +08:00
    time() . rand(00000000,99999999)
    wzzyj8
        24
    wzzyj8  
       2014-10-26 22:55:41 +08:00   ❤️ 1
    @spance PHP开发有PHP开发的玩法,HFT有HFT的玩法,小的初创公司等按照开发HFT系统的模式开发好一套电商程序开门营业,恐怕类似的想法早就被别人占据了先机。
    明明是很容易实现的事情真的不懂为什么难实现。各种语言各有所长,何必互相贬低。
    iyaozhen
        25
    iyaozhen  
       2014-10-26 22:56:36 +08:00
    @imydou 如果两个单子时间十分接近,用随机数(随机数并不能保证随机)可能会重复。
    wdlth
        26
    wdlth  
       2014-10-26 23:22:36 +08:00
    如果对高并发有要求的话可以由数据库完成全局唯一ID生成,而不是由服务器端语言来。
    guoer
        27
    guoer  
       2014-10-26 23:55:44 +08:00
    私以为要加个校验位
    zhengkai
        28
    zhengkai  
       2014-10-27 00:02:08 +08:00
    如果的订单量峰值少于 2000条/秒,直接用数据库的自增长就可以了
    breeswish
        29
    breeswish  
       2014-10-27 09:03:41 +08:00
    uniqid() 就能确保一定不重复了..
    cdffh
        30
    cdffh  
       2014-10-27 09:23:00 +08:00
    uniqid ( time (), true )
    Actrace
        31
    Actrace  
       2014-10-27 09:56:34 +08:00
    MYIASM表的自增长,看你怎么冲突....
    mgc
        32
    mgc  
       2014-10-27 10:08:28 +08:00
    @spance 不值得一辩,是不是想说金融高并发都必须用C#开发
    macdino
        33
    macdino  
       2014-10-27 10:55:55 +08:00
    万物的存在,哪就有一定的道理。语言好与不好,不是你一个人说了算滴。各种语言都有各种语方的优缺点,何必一上来就上纲上线的。@spance
    fengchang
        34
    fengchang  
       2014-10-27 10:56:21 +08:00
    看到@spance的回复我就惊呆了,拉回去又读了三遍主题
    esile
        35
    esile  
       2014-10-27 12:32:36 +08:00
    年月日时分秒+随机数
    wwek
        36
    wwek  
       2014-10-27 14:06:42 +08:00
    虽然用uuid uniqid什么的 可以唯一。但是如果我只想纯数字的呢?

    多机php负载均衡的情况下呢?
    wwek
        37
    wwek  
       2014-10-27 14:14:35 +08:00
    /**
    * 得到新订单号
    * @return string
    */
    function get_order_sn()
    {
    /* 选择一个随机的方案 */
    mt_srand((double) microtime() * 1000000);

    return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
    }
    这是 ecshop的
    anewg
        38
    anewg  
       2014-10-27 14:27:05 +08:00
    @wwek 多机的话 uniqid 有 prefix 参数
    muziyue
        39
    muziyue  
       2014-10-27 14:51:08 +08:00
    @wwek 数据库自增加工一下就可以啊,而且不会重复,纯数字
    bystand3r
        40
    bystand3r  
       2014-10-27 15:23:33 +08:00
    /**
    * 生成16位纯数字订单号
    * 最大支持时间到 2056-12-31 23:59:59
    *
    * @access public
    * @return string
    */
    public static function getOrderSN() {
    return (date('y') + date('m') + date('d')) . str_pad((time() - strtotime(date('Y-m-d'))), 5, 0, STR_PAD_LEFT) . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999));
    }

    目前在用的,基本保证不重复了,能用到2056年,觉得应该够了,以后有需求再扩展
    maxsec
        41
    maxsec  
       2014-10-27 18:23:35 +08:00
    @spance 目测你还在学校擦皮鞋吧
    jevonszmx
        42
    jevonszmx  
       2014-10-27 18:24:59 +08:00
    其实参考成熟的方案就可以看出一般做法了
    比如淘宝的订单号839175861614813
    最后四位同一个用户一定是一样的
    前面如果可以用字符串的话可以使用日期(方便分类和追溯)+ 类型id + 订单id,再加上进制转换,可以实现很大的数量级;


    订单id,如果觉得php无法实现原子性,可以使用mysql、redis等,完全没问题啊。
    wwek
        43
    wwek  
       2014-10-27 20:02:21 +08:00
    @bystand3r 不错!~

    @jevonszmx 淘宝的很不错·
    dong3580
        44
    dong3580  
       2014-11-02 18:00:23 +08:00
    GUID,或者时间戳,或者增量种子生成。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2580 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:36 · PVG 11:36 · LAX 19:36 · JFK 22:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.