ホームページ > バックエンド開発 > PHPチュートリアル > php订单号方案,重复的可能性要很低很低很低,大家说说自己的方案。

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

WBOY
リリース: 2016-06-06 20:41:55
オリジナル
1136 人が閲覧しました

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

回复内容:

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

我的算法是:

买家UID+商家UID+年月日+三位随机数

大家觉得怎么样?

我来说下对京东ID编号的看法,两年前京东订单就突破2亿,现在应该超过四个亿了,十位订单最长才99亿,从这个占比来说,京东的订单号应该不是简单某种随机算法做出来的,如果是随机算法做出来的,肯定要做二次检验,ID是否已存在,如果存在就再生成新的。根据我分析自己在京东购买东西实际编号,丫就是按从小到大生成的
我估计有个外置ID生成服务器,要不然肯定抗不住双11这种,比如可以有一台专门服务器分多个进程,每个进程负责10万个编号分配,没有了就再申请,进程间的编号独立,或者简单点每台应用服务器就有个专属ID区域。

我们这的方式就是:
时间戳 + 机器编号 + 0-1000循环编号

首先时间戳是不会重复的,好像这样就保证了不重复吧。

我看了下淘宝的订单和账户有关。 同一个账户对同一个商家的订单号尾数好像。。是一样的

有反馈下面代码,不靠谱,冲撞率极高,这里就仅做学习,不推荐正式环境使用了

<code>    /**
     *
     * uniqid - 官方是这样说的:
     * Gets a prefixed unique identifier based on the current time in microseconds.
     */
    function build_order_no()
    {
        return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }</code>
ログイン後にコピー

补充:来自ECSHOP订单号生成函数:/includes/lib_order.php文件中的get_order_sn()

<code>/**
 * 得到新订单号
 * @return  string
 */
function build_order_no()
{
    /* 选择一个随机的方案 */
    mt_srand((double) microtime() * 1000000);
 
    return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
}</code>
ログイン後にコピー

from :http://levi.cg.am/archives/3373

有一个东西叫 UKG 专门来干这个事情的。可以了解下:https://github.com/liexusong/ukg

我觉得uniqid就行
http://php.net/manual/zh/function.uniqid.php

可以 参考一下 ecshop 的订单生成机制

<code>return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); 
</code>
ログイン後にコピー

$str = date('ymd') . substr(implode(null, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
或者
$yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
$orderSn = $yCode[intval(date('Y')) - 1970] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%04d%02d', rand(1000, 9999), rand(0, 99));

上面的方案生成的订单号比较长,京东的十位订单号是怎么生成和保证不重复的呢?

订单编号在什么时候生成?怎样避免生成重复的?事务安全?存储过程?

sys_guid

为什么我想用hash做订单号……

<code>/*
 * 得到唯一的订单编号
 * @params null
 * @return string 订单编号
 */
/** preterchan **/
public function gen_id($n=0, $data_format='ymdHi')
{
    $i = rand(0,99999);
    do{
        if(99999==$i){
            $i=0;
        }
        $i++;
        $order_id = date($data_format).str_pad($i,5,'0',STR_PAD_LEFT);
        if ($n) $order_id .= $n;
        $row = $this->db->selectrow('SELECT order_id from orders where order_id ='.$order_id);
    }while($row);
    return $order_id;
} 
</code>
ログイン後にコピー

生成出的数字转换成36进制(数字+26个字母),可以缩短长度
比如 :

<code> //会员号 + 秒 + 微秒 + 随机
$mid=118914;
list($usec, $sec) = explode(" ", microtime());
$rand=rand(1000,9999);
echo strtoupper(base_convert($mid,10,36).base_convert($sec,10,36).base_convert($usec*10000000,10,36).base_convert($rand,10,36));
//2JR6NE7JXQ5SPY85BY
</code>
ログイン後にコピー

如果没有别的前提要求,自增长就足够了...
我之前一个项目的要求是不能让用户看出是怎么生成的,表面上看起来要完全随机
那么加时间戳也会被看出来,使用用户uid也会被看出来,随机生成又有可能出现重复
最后是这样做的

<code>        $time_order=time();
        list($usec, $sec)=explode(" ", microtime());
        $orderid=substr($uid*rand(11,55),0,5);
        $orderid.=date('ymdHis',$sec).ceil($usec*10);
        $orderid=substr($orderid,0,18);
</code>
ログイン後にコピー
関連ラベル:
php
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート