2018年8月10日08:53:50

一般生产订单号的方式

1,使用时期+随机数1+随机数2

缺点,有可能在并发的时候会出现重复,解决办法就是加唯一索引,在插入数据的做查询是否已经被使用

2,使用时间+统计当前订单数,按订单数+1,很多系统使用这种

缺点,如果有需要删除数据,当然脑残的需求,但是还是会有,再次下单就会出现订单重复,这种非常不好改动

个人建议:时间按照年+月,不要用日  201810+000000000011这种

参考1:金蝶k3,会有一个全局使用的ID,通过触发器增长

参考2:经验之谈,全局计数器解决2个根本问题,订单号不重复,使用一次请求一次,返回最近的计算结果,2不会因为删除订单出现订单号重复

数据库

--计数器表
CREATE TABLE `counter` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL COMMENT '名称',
`value` bigint(20) unsigned DEFAULT '1' COMMENT '存储的值',
`create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间',
`tag` varchar(50) DEFAULT NULL COMMENT '标签',
`type` tinyint(1) NOT NULL DEFAULT '10' COMMENT '类型10采购订单20销售订单30自营物流号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='计数器表';

注意我存储的 value是bigint 20,足够大

 //计数器
public static function counter($type = null) {
if (empty($type)) {
throw new \Exception('tag标签不能为空');
}
$now = time();
$time = date('Ym', $now);
$time1 = date('Ym', $now);
$tag = self::counter_array($type);
$name = $time . '_' . $tag; DB::beginTransaction();
try {
$Counter = Counter::where('name', $name)->lockForUpdate()->first(['value', 'id']);
if (empty($Counter)) {
//没有就插入
$Counter = new Counter;
$Counter->name = $name;
$Counter->type = $type;
$Counter->tag = $tag;
$Counter->save();
$Counter = Counter::where('name', $name)->first(['value', 'id']);
} $Counter = $Counter->toArray();
//加锁 防止生成的订单号出错,没有在name上加索引
Counter::where('id', $Counter['id'])->lockForUpdate()->first(); if ($type == 40) {
$new_count = (float) $Counter['value'] + 1;
Counter::where('name', $name)->update(['value' => $new_count]);
$string = $time1 . str_pad($new_count, 6, '0', STR_PAD_LEFT);
} else {
$new_count = (float) $Counter['value'] + 3;
Counter::where('name', $name)->update(['value' => $new_count]);
$string = $time . str_pad($new_count, 12, '0', STR_PAD_LEFT);
} DB::commit();
return $string;
} catch (\Exception $e) {
DB::rollBack();
throw new \Exception($e->getMessage());
}
} //订单计数器映射数组
public static function counter_array($type = null) {
//采购订单号
$array['10'] = 'sales_order_number';
//销售订单号
$array['20'] = 'purchase_order_number';
//自营物流订单号
$array['30'] = 'logistics_order_number';
//入库订单号
$array['40'] = 'inbound_order_number';
//出库订单号
$array['50'] = 'outbound_order_number';
if (empty($type)) {
return $array;
}
return $array[$type];
}
Counter::where('id', $Counter['id'])->lockForUpdate()->first();必须在事务里面使用

解释一下为什么不适用 全局订单不是+1而是+3,防止有特殊订单需要插入,同时不让计数器的数字增长太快

还有必须加锁,虽然有事务,但是还是要加锁,订单长度自己选择填充长度,我定义的是20个长度,足够了14位长度的除以3的长度,足够了

有人会担心新能,我只能说你想多了,这点压力都扛不住,不可能,见过随时写入mysql,随时读取的操作吗?这么糙的逻辑代码mysql都能满足

订单号给个建议就是 采用

$time = date('Ym', $now);不要使用年月日,因为有些行业特殊性,最好采用年月这种模式,统计时间去使用创建时间做数据统计

使用mysql设计一个全局订单生产计数器的更多相关文章

  1. 180626-Spring之借助Redis设计一个简单访问计数器

    文章链接:https://liuyueyi.github.io/hexblog/2018/06/26/180626-Spring之借助Redis设计一个简单访问计数器/ Spring之借助Redis设 ...

  2. 设计一个BCD码计数器。

    BCD码计数器的定义: 对于机器语言,机器与人不同,为了让人更好的了解机器语言的数据输出,选用4位二进制数据表示十进制里的每位数据,这便是BCD码. 以下便是BCD码与十进制对应的码表 0------ ...

  3. MySQL系列(十二)--如何设计一个关系型数据库(基本思路)

    设计一个关系型数据库,也就是设计RDBMS(Relational Database Management System),这个问题考验的是对RDBMS各个模块的划分, 以及对数据库结构的了解.只要讲述 ...

  4. mysql设计-基本操作

    mysql 设计 1)服务器管理 2)数据库管理 3)表管理 4)字段管理 5)索引管理 操作 1)sql语句 2)单表操作 3)多表操作 索引 记录 字段 mysam innodb ibdata1 ...

  5. MySQL中的全局锁和表级锁

    全局锁和表锁 数据库锁设计的初衷是解决并发出现的一些问题.当出现并发访问的时候,数据库需要合理的控制资源的访问规则.而锁就是访问规则的重要数据结构. 根据锁的范围,分为全局锁.表级锁和行级锁三类. 全 ...

  6. 如何设计一个分布式 ID 发号器?

    大家好,我是树哥. 在复杂的分布式系统中,往往需要对大量的数据和消息进行唯一标识,例如:分库分表的 ID 主键.分布式追踪的请求 ID 等等.于是,设计「分布式 ID 发号器」就成为了一个非常常见的系 ...

  7. 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文

    阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...

  8. 设计一个较好的框架的难点之一--API兼容性的设计

    设计一个好的框架和设计一个好的软件一样,需要考虑的方面很多,比如扩展性.性能.用户体验.稳健性等等,视不同的场景,每个点都可能导致成败,但他们通常并不是老板们关心的,因为在大部分情况下,他们通常都没有 ...

  9. MySQL创建一个用户,指定一个数据库 授权

    Mysql 创建一个用户 hail,密码 hail,指定一个数据库 haildb 给 hail mysql -u root -ppassworduse mysql;insert into user(h ...

随机推荐

  1. 【原创】大数据基础之Oozie(2)使用

    命令行 $ oozie help 1 导出环境变量 $ export OOZIE_URL=http://oozie_server:11000/oozie 否则都需要增加 -oozie 参数,比如 $ ...

  2. 剑指offer数组列表

    一.数组 面试题3 : 找出数组中重复的数字 面试题3(二):不修改数组找出重复的数字 面试题4:二维数组的查找 面试题21:调整数组顺序使奇数位于偶数前面 面试题39:数组中出现次数超过一半的数字 ...

  3. 办公用品管理系统VB——库存数量导出EXCEL,SaveEXCEL

    办公用品管理系统VB——库存数量导出EXCEL,SaveEXCEL 总体来说,VB的EXCEL导出效率还是蛮低的,就是一个小型化的办公用品管理软件,不再优化了. 时间紧迫,就没有从头到尾的用C#编写, ...

  4. HTTP 403 ,tomcat配置HTTPS,无法访问 返回状态码HTTP 403

    为了将本机(windows系统)启动的应用以HTTPS的形式访问, 利用Keytool 生成证书之后.在tomcat的server.xml中将配置修改为如下: <Connector port=& ...

  5. 提取C3D视频特征(官方文档&实践)

    C3D Introduction 卷积神经网络(CNN)近年被广泛应用于计算机视觉中,包括分类.检测.分割等任务.这些任务一般都是针对图像进行的,使用的是二维卷积(即卷积核的维度为二维).而基于视频的 ...

  6. Android+openCV人脸检测2(静态图片)

    前几篇文章中有提到对openCV环境配置,这里再重新梳理导入和使用openCV进行简单的人脸检测(包括使用级联分类器) 一 首先导入openCVLibrary320 二 设置gradle的sdk版本号 ...

  7. 大数据小白系列 —— MapReduce流程的深入说明

    上一期我们介绍了MR的基本流程与概念,本期稍微深入了解一下这个流程,尤其是比较重要但相对较少被提及的Shuffling过程. Mapping 上期我们说过,每一个mapper进程接收并处理一块数据,这 ...

  8. 转载:使用Tornado+Redis维护ADSL拨号服务器代理池

    我们尝试维护过一个免费的代理池,但是代理池效果用过就知道了,毕竟里面有大量免费代理,虽然这些代理是可用的,但是既然我们能刷到这个免费代理,别人也能呀,所以就导致这个代理同时被很多人使用来抓取网站,所以 ...

  9. XIV Open Cup named after E.V. Pankratiev. GP of Europe

    A. The Motorway 等价于找到最小和最大的$L$满足存在$S$使得$S+(i-1)L\leq a_i\leq S+i\times L$ 即 $S\leq\min((1-i)L+a_i)$ ...

  10. CSS(八)

    CSS3 transform变换 1.translate(x,y) 设置盒子位移2.scale(x,y) 设置盒子缩放3.rotate(deg) 设置盒子旋转4.skew(x-angle,y-angl ...