http://blog.itpub.net/22664653/viewspace-2079576/

开发反馈一个表的数据大小已经130G,对物理存储空间有影响,且不容易做数据库ddl变更。咨询了开发相关业务逻辑,在电商业务系统中,每笔订单成交之后会有一条对应的订单物流信息,因此需要设计一个物流相关的表用来存储该订单的物流节点信息,该表使用text字段存储物流信息。

大致的表结构:
CREATE TABLE `goods_order_express` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `express_id` int(10) unsigned NOT NULL,
  `message` varchar(200) NOT NULL,
  `status` varchar(20) NOT NULL,
  `state` tinyint(3) unsigned NOT NULL,
  `data` text NOT NULL,
  `created_time` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_expid` (`express_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;

业务分析
当快递每到达一个中转站或者发生揽件,接收等事件,快递公司的api都会生成如下格式的信息(去掉业务相关敏感数据) 
[{"time":"2016-03-16 11:16:20","ftime":"2016-03-16 11:16:20","context":"四川省成都市TD客户一公司 已发出,下一站成都转运中心","areaCode":"","areaName":"","status":"在途"},{"time":"2016-03-16 11:11:03","ftime":"2016-03-16 11:11:03","context":"四川省成都市TD客户一公司 已打包","areaCode":"","areaName":"","status":"在途"},{"time":"2016-03-16 11:08:09","ftime":"2016-03-16 11:08:09","context":"四川省成都市TD客户一公司 已揽收","areaCode":"","areaName":"","status":"收件"}]
该json 串 411个字符,开发业务程序去定期轮训调用相关api信息,并把上面的json串数据 insert 或者update 到goods_order_express的data字段。而且该表从开始到现在从未删除,积累了初始到现在的所有数据。随着公司业务爆发式增长,该表未来会更大,而且增长速度会更快。数据库服务器的磁盘空间面临不足,表结构变更难以操作。
如何优化?
1 能否减小数据量写入?
   和业务分析,我们不能丢弃新增的数据。但是每一笔物流信息实际上是有生命周期的,从发货到收件完成即可完成其生命周期,也就是该数据可以不再展示了,我们基本不会查看一个已经收到货的物流信息。因此可以针对历史数据进行归档,比如将90天之前的数据备份到hbase中并且从MySQL 数据库中删除,从而维持该表的大小在一个合理的范围。
2 减少data 字段数据大小
a 缩小json串数据,保留有效数据
time 和ftime 是一样的,和开发确认ftime无功能使用,在我们的物流展示系统中 areaCode areaName也没有逻辑意义。
故对json数据做如下精简 
[{"time":"2016-03-16 11:16:20","context":"四川省成都市TD客户一公司 已发出,下一站 成都转运中心","status":"在途"},{"time":"2016-03-16 11:11:03","context":"四川省成都市TD客户一公司 已打包","status":"在途"},{"time":"2016-03-16 11:08:09","context":"四川省成都市TD客户一公司 已揽收","status":"收件"}]
精简之后占用的字符数由411个减小为237个,减少47%的数据。
b 评估物流节点数
相信大家都有网购的经验 ,一般情况下快递大约含有15-20个节点信息
{"time":"2016-03-16 11:16:20","context":"四川省成都市TD客户一公司 已发出,下一站 成都转运中心","status":"在途"} 占用85个,我们按照100个字符来评估,物流信息最大20*100=2000个字符,使用varchar(2048) 应该可以满足正常需求。
c 可能有人会说凡事总有例外,那我们从这个例外分析一下 如果一个物流有30或者40个节点信息 怎么办?
从深圳到黑龙江漠河 或者新疆乌鲁木齐到杭州,上海的节点信息估计会比较多。对于20个以上 的节点信息 我们不会去关注其中第10个 11个 14个 15个节点的信息。大家对快递的关注点是什么? 商家是否发货?快递公司是否揽件? 快递是否到达目的地的最后1公里。分析到这里,我们可以针对超过25个/30个以上的节点进行收缩处理,去掉中间非核心节点信息,在不影响用户体验的情况下,满足我们的varchar(2048)的设计。
3 分库分表
  这点是迫不得已而为之的方案。现在虽然各种中间件都比较成熟,cobar,oneproxy ,mycat等靠谱的软件,但是对于一个创业公司目前我们还缺少相对应的分布式数据库的管理工具,1024个表如何做变更?这个其实也是一个相对比较困难的问题。

4 冗余关系表

新建一张表用来分解JSON字段的信息,使用一张表来记录这些信息

小结 
   经过一系列的分析和优化,我们最终将text字段转化为varchar(2048),发布到线上目前运行良好。回顾上面的优化过程是建立在对业务逻辑和物流相关知识有深入理解,对用户行为多加分析的基础之上的,该过程不需要高深的数据库知识。但是实际上开发往往简单粗暴的接受pd的功能设计理念,而不顾对底层基础架构的影响。其实只需要向前多走一步,我们可以做的更好,只不过这一步,可能是 优秀的程序员的一小步,是某些人的一大步。
留给大家一个问题:如何看待和解决 开发快速迭代带来的技术债?

1122从业务优化MYSQL的更多相关文章

  1. 优化MySQL的21个建议 – MySQL Life【转】

    今天一个朋友向我咨询怎么去优化 MySQL,我按着思维整理了一下,大概粗的可以分为21个方向. 还有一些细节东西(table cache, 表设计,索引设计,程序端缓存之类的)先不列了,对一个系统,初 ...

  2. 如何优化MySQL千万级大表

    很好的一篇博客,转载 如何优化MySQL千万级大表 原文链接::https://blog.csdn.net/yangjianrong1985/article/details/102675334 千万级 ...

  3. 从零到千万用户,我是如何一步步优化MySQL数据库的?

    写在前面 很多小伙伴留言说让我写一些工作过程中的真实案例,写些啥呢?想来想去,写一篇我在以前公司从零开始到用户超千万的数据库架构升级演变的过程吧. 本文记录了我之前初到一家创业公司,从零开始到用户超千 ...

  4. 简单的方式优化mysql

    参考博客 自己笔记本上向mysql导入txt数据,有一个table导入了将近4个小时,而且多个table之间都是相互之间存在关系的,所以做联合查询的时候你会发现问题会十分的多,我之前联合查询两个表就死 ...

  5. TCMalloc优化MySQL、Nginx内存管理

    TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员. 与标准的glibc库的Malloc相比,TCMalloc库在内存 ...

  6. 优化MySQL,还是使用缓存?读一篇文章有感

    今天我想对一个Greenfield项目上可以采用的各种性能优化策略作个对比.换言之,该项目没有之前决策强加给它的各种约束限制,也还没有被优化过. 具体来说,我想比较的两种优化策略是优化MySQL和缓存 ...

  7. jemalloc优化MySQL、Nginx内存管理

    上一篇文章<TCMalloc优化MySQL.Nginx.Redis内存管理>,下面来看下jemalloc jemalloc源于Jason Evans 2006年在BSDcan confer ...

  8. TCMalloc优化MySQL、Nginx、Redis内存管理

    TCMalloc(Thread-Caching Malloc)与标准glibc库的malloc实现一样的功能,但是TCMalloc在效率和速度效率都比标准malloc高很多.TCMalloc是 goo ...

  9. MYSQL之性能优化 ----MySQL性能优化必备25条

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我 们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数 ...

随机推荐

  1. 【Swift 2.1】共享文件操作小结(iOS 8 +)

    前言 适用于 iOS 8 + 本地共享文件列表 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs ...

  2. 添加 All Exceptions 断点后, 每次运行都会在 main.m 中断的一种解决方法

    在本人项目添加导入和使用新的字体过程中,遇到一个很奇怪的问题: 项目开启了全局断点,但是每次启动都会运行在mian.m中断,点击下一步程序继续正常运行. 不知道是什么原因,于是google百度寻找答案 ...

  3. android 事件分发机制

    1.View的事件分发机制 一个button,简单一点就是onTouch,还有onclick事件,我们一个一个来分析 首先响应的是dispatchTouchEvent public boolean d ...

  4. configure Git to accept a particular self-signed server certificate for a particular https remote

    get the self signed certificate put it into some (e.g. ~/git-certs/cert.pem) file set git to trust t ...

  5. nodejs 中自定义事件

    经常看到 req.on('error', function(){...}); 这种代码. 在nodejs中,可以使用 EventEmitter来实现. 具体的关键词有如下几个: var reqEven ...

  6. Linux 平台MySQL启动关闭方式总结

    MySQL的启动方法有很多种,下面对比.总结这几种方法的一些差异和特性,下面实验的版本为MySQL 5.6.如有疏漏或不足,敬请指点一二.   1:使用mysqld启动.关闭MySQL服务 mysql ...

  7. SSRS Reports 2008性能优化案例二

    前几天一同事反映海外工厂A的SSRS报表比较慢,让我检查优化一下.于是我检查了下2015-07-13到2015-07-15 12:00这段时间报表的耗时记录 USE [ReportServer];   ...

  8. php应用jquery做ajax操作

    以下是全部代码: <html> <head> <title>jQuery Ajax 实例演示</title> </head> <scr ...

  9. 设置 Unix,Linux环境下的NLS_LANG

    设置 NLS_LANG 变量 1) 正确配置 LC_ALL 参数 2) 配置 telnet/ssh/SecureCRT 客户端的字符集 linux中可以用locale命令来查看 NLS_LANG设置, ...

  10. 通过PHP自带的$_SERVER判断 手机访问网站自动跳转到手机版

    需要有PC版网站和移动版网站,当手机访问域名的时候,通过PHP自带的$_SERVER判断浏览设备并跳转到移动版页面.如果是PC电脑打开网址,则不跳转直接访问pc版. <?php //php判断客 ...