订单号生成规则 系统时间随即号|系统时间数据库自增号
前阵子,公司有个电子商务项目,需要生成订单号。当时的考虑很简单,取系统时间加上随机数,或者使用 uniqid() 方法。我们都知道,订单号最基本的要求就是唯一,这个条件必须满足。仔细考虑下上述方法,在顾客购买量少的情况下,订单重复的可能性为零,但是在购买高蜂期生成的订单号重复是很有可能发生的 。所以上述方法不可靠,有待强化。
用上了英文字母、年月日、Unix 时间戳和微秒数、随机数,重复的可能性大大降低,还是很不错的。使用字母很有代表性,一个字母对应一个年份,总共16位,不多也不少,呵呵。substr(time(), -3)
function get_order_sn($year='2011'){
$yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
$index = intval(date('Y')) - $year;
if($index<0){
$index =0;
}
if($index>count($yCode)-1){
$index =count($yCode)-1;
}
$perfix = $yCode[$index] . strtoupper(dechex(date('m'))) . date('d');
$rand_num = substr(time(), -5) . substr(microtime(), 2, 5).sprintf('%03d', rand(0, 99));
$orderSn = $perfix . $rand_num;
return $orderSn;
}
第三种
//生成24位唯一订单号码,格式:YYYY-MMDD-HHII-SS-NNNN,NNNN-CC,其中:YYYY=年份,MM=月份,DD=日期,HH=24格式小时,II=分,SS=秒,NNNNNNNN=随机数,CC=检查码
function get_order_sn($user_id)
{
//订单号码主体(YYYYMMDDHHIISSNNNNNNNN)
$order_id_main = date('YmdHis') . rand(10000000, 99999999);
//订单号码主体长度
$order_id_len = strlen($order_id_main);
$order_id_sum = 0;
for ($i = 0; $i < $order_id_len; $i++) {
$order_id_sum += (int)(substr($order_id_main, $i, 1));
}
//唯一订单号码(YYYYMMDDHHIISSNNNNNNNNCC)
return $order_id_main . str_pad((100 - $order_id_sum % 100) % 100, 2, '0', STR_PAD_LEFT) . $user_id;
}
第四种
function get_order_sn()
{
return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
方法五:生成的号码是递增的
function get_order_sn()
{
list($usec, $sec) = explode(' ', microtime());
return date('YmdHis', $sec).str_pad(floor($usec * 1000000), 6, '0', STR_PAD_LEFT);
}
如果生成的订单要求订单号必须是连续的,并发加锁 ,要保证订单连续订单号必须在订单生成的同时++,但是多人同时操作时会出现订单号相同的冲突。解决方法:http://hudeyong926.iteye.com/blog/894823
建立一张订单号预约表,表中的订单号有效期1个小时,在有效期内被预约的号码会被用户占用,和优先使用,其他人不能使用,超过1小时就表示放弃了预约,如果用户还是用的是这个号码,就提示订单号失效了,用户必须重新获取订单号在继续操作。其他用户可以使用该号码。
当用户1在订单作业时,在使用订单号200910G0016时,这个订单号就被预约了,其他人就不能使用它了,其他人就只能用下一个订单号。在一个小时内,用户1没有完成一单,不管怎样重新下单他就只能使用订单号200910G0016,超过1小时候就不能使用了。如果完成了预约(将订单号200910G0016生成了一张订单,就要删除这个号)。
JAVA版
/**
* 生成订单流水号
*
* @param prefix 前缀
* @return
*/
public static String generateOrderNo(String prefix, Integer len) {
SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, len);
return prefix + (sdf.format(new Date()) + uuid).toUpperCase();
}