444683462
V2EX  ›  问与答

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

  •  
  •   444683462 · Oct 26, 2014 · 6910 views
    This topic created in 4397 days ago, the information mentioned may be changed or developed.
    php订单号方案,重复的可能性要很低很低很低,大家说说自己的方案。
    44 replies  •  2014-11-02 18:00:23 +08:00
    abelyao
    abelyao
    Oct 26, 2014
    1
    有长度要求吗?有排序要求吗?纯数字还说可英文?并发量估计会去到多少?
    bystand3r
    bystand3r
    Oct 26, 2014
    2
    同楼上……你的格式要求呢……给你来个1024位的?
    sy1989
    sy1989
    Oct 26, 2014
    3
    mysql 的自增好了
    arslion
    arslion
    Oct 26, 2014
    4
    @sy1989 +1
    vibbow
    vibbow
    Oct 26, 2014
    5
    用 UUID
    imn1
    imn1
    Oct 26, 2014
    6
    类别+时间+随机数
    yylzcom
    yylzcom
    Oct 26, 2014
    7
    timestamp+userid(+random number)
    xiaoyaoking
    xiaoyaoking
    Oct 26, 2014
    8
    7 楼正解, 其实 timestamp 就不会重复了。。 想要长度就 timestamp md5 妥妥的。
    orvice
    orvice
    Oct 26, 2014
    9
    时间(精确到秒)+随机数基本就可以了吧
    spance
    spance
    Oct 26, 2014
    10
    PHP很难做到。

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

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

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

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

    多机php负载均衡的情况下呢?
    wwek
    wwek
    Oct 27, 2014
    37
    /**
    * 得到新订单号
    * @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
    anewg
    Oct 27, 2014
    38
    @wwek 多机的话 uniqid 有 prefix 参数
    muziyue
    muziyue
    Oct 27, 2014
    39
    @wwek 数据库自增加工一下就可以啊,而且不会重复,纯数字
    bystand3r
    bystand3r
    Oct 27, 2014
    40
    /**
    * 生成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
    maxsec
    Oct 27, 2014
    41
    @spance 目测你还在学校擦皮鞋吧
    jevonszmx
    jevonszmx
    Oct 27, 2014
    42
    其实参考成熟的方案就可以看出一般做法了
    比如淘宝的订单号839175861614813
    最后四位同一个用户一定是一样的
    前面如果可以用字符串的话可以使用日期(方便分类和追溯)+ 类型id + 订单id,再加上进制转换,可以实现很大的数量级;


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

    @jevonszmx 淘宝的很不错·
    dong3580
    dong3580
    Nov 2, 2014
    44
    GUID,或者时间戳,或者增量种子生成。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   985 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 132ms · UTC 22:16 · PVG 06:16 · LAX 14:16 · JFK 17:16
    ♥ Do have faith in what you're doing.