生成规则设计 http://hudeyong926.iteye.com/blog/1860360
订单号生成规则 系统时间随即号|系统时间数据库自增号
前阵子,公司有个电子商务项目,需要生成订单号。当时的考虑很简单,取系统时间加上随机数,或者使用 uniqid() 方法。我们都知道,订单号最基本的要求就是唯一,这个条件必须满足。仔细考虑下上述方法,在顾客购买量少的情况下,订单重复的可能性为零,但是在购买高蜂期生成的订单号重复是很有可能发生的 。所以上述方法不可靠,有待强化。
- function get_order_sn(){
- //原来的订单号形式为:年月日 + 5位随机数字,例如:2012042096200
- return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
- }
用上了英文字母、年月日、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(uniqid(),-6).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()
- {
- //订单号码主体(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);
- }
第四种
- function get_order_sn()
- {
- return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
- }
1.如果生成订单不要求订单号连续,订单号CHAR(6)NOT NULL DEFAULT '',先保存订单后得到自增的主键,再根据主键更新订单号,高并发也不存在问题,推荐此方法 。
- $id = last_insert_id();
- 'M'. str_pad($id, 5, '0', STR_PAD_LEFT);
2.如果生成的订单要求订单号必须是连续的,并发加锁 ,要保证订单连续订单号必须在订单生成的同时++,但是多人同时操作时会出现订单号相同的冲突。解决方法:http://hudeyong926.iteye.com/blog/894823
- $sql="SELECT `next_seq` FROM `create_seq_num` LIMIT 1;UPDATE `create_seq_num` SET `next_num`=`next_num` + 1";
建立一张订单号预约表,表中的订单号有效期1个小时,在有效期内被预约的号码会被用户占用,和优先使用,其他人不能使用,超过1小时就表示放弃了预约,如果用户还是用的是这个号码,就提示订单号失效了,用户必须重新获取订单号在继续操作。其他用户可以使用该号码。
当用户1在订单作业时,在使用订单号200910G0016时,这个订单号就被预约了,其他人就不能使用它了,其他人就只能用下一个订单号。在一个小时内,用户1没有完成一单,不管怎样重新下单他就只能使用订单号200910G0016,超过1小时候就不能使用了。如果完成了预约(将订单号200910G0016生成了一张订单,就要删除这个号)。