当项目上线后,随着用户的增长,有些数据表的规模会以几何级增长,当数据达到一定规模的时候(例如100万条),查询,读取性能就下降得很厉害,这时,我们就要考虑分表。

更新表数据时会导致索引更新,当单表数据量很大时这个过程比较耗时,这就是为什么对大表进行新增操作会比较慢的原因,并且更新表数据会进行表级锁或者行锁,这样就导致其他操作等待。

所以我们将大表拆分为多个子表,那么在更新或者查询数据的时候,压力会分散到不同的表上。由于分表之后每个表的数据较小,不管是查询还是更新都极大的提高了速度,即使出现最坏的“锁表”的情况,那其他表还是可以并行使用。

1.分表的策略

分表有多种策略:

(1)按用户id分表,例如id为1-10000在表1,id为10001-20000在表2

(2)插入的时间分表

(3)按每个表固定记录行数拆分

在项目,由于这个表是保存用户的通讯录,为了保证一个用户的所有通讯录数据都保存在同一个表,选择的分表方式就是(1),按用户id分表。

2. 分表策略确定下来了,还有一个非常严重的问题,因为现在用户的数据都分散在不同的表中,之前的业务功能如何保证呢?比如说我要插入一条记录、更新一条记录、删除一条记录、查询统计数据,现在要怎么处理呢?

如果分表的存储引擎是MyISAM,这里有一种很简单的处理方法。利用merge存储引擎将拆分的表合并成一张表。当然了,如果使用InnoDB,也能通过alter table命令把InnoDB变为MyISAM。

MERGE存储引擎可以将N个子表联合在一起,看成是一个整表,实际上还是N个真实的子表。

当分表的时候,还要一个问题,因为我们是在线上项目中分表的,需要考虑怎么样使分表的操作对用户的影响最少。

3. 一个例子

假设有表contact,存储了9000个用户的通讯录数据,平均一个用户有联系人100个,那么这个表的规模就达到了90万条数据,我们需要对这个表分表。

下面的脚本演示了怎么在不关闭MySQL服务的情况下对contact 分表

  1. -- ----------------------------
  2. -- 创建根据原来的表格式创建一个临时表,并把存储引擎改为MYISAM
  3. -- ---------------------------
  4. CREATE TABLE contact_temp LIKE contact;
  5. ALTER TABLE contact_temp ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci ;
  6.  
  7. -- ----------------------------
  8. -- 创建分表contact_temp1contact_temp2
  9. -- ---------------------------
  10. CREATE TABLE contact_temp1 LIKE contact_temp;
  11. CREATE TABLE contact_temp2 LIKE contact_temp;
  12.  
  13. -- ----------------------------
  14. -- 按用户id分表,把id<5000 保存在表1id>=5000 and id<10000 保存在表2
  15. -- ----------------------------
  16. INSERT INTO contact_temp1 SELECT * FROM contact where uid<5000;
  17. INSERT INTO contact_temp2 SELECT * FROM contact where uid>=5000 and uid<10000;
  18.  
  19. -- ----------------------------
  20. -- 把原来的表改名,因为在mysql中不能有重复的表明,这样子最终创建的MERGE引擎的表就能使用原来的表名
  21. -- ----------------------------
  22. RENAME TABLE contact TO contact_bak;
  23. CREATE TABLE contact LIKE contact_temp;
  24.  
  25. -- ----------------------------
  26. -- 先把原来删除表上的主键的自增属性去掉,再删除主键
  27. -- ----------------------------
  28. ALTER TABLE contact CHANGE `id` `id` int(11);
  29. ALTER TABLE contact DROP PRIMARY KEY;
  30.  
  31. -- ----------------------------
  32. -- 把表的存储引擎改为MERGE
  33. -- ----------------------------
  34. ALTER TABLE contact ENGINE=MERGE UNION=(contact_temp1,contact_temp2) INSERT_METHOD=LAST;
  35.  
  36. -- ----------------------------
  37. -- 删除所有的临时表
  38. -- ----------------------------
  39. drop TABLE contact_bak;
  40. drop TABLE contact_temp;

app后端设计-- 数据库分表的更多相关文章

  1. app后端设计--总目录 (转)

    特此说明,我转载的!!! app后端设计(1)--api app后端设计(2)--xmpp的使用 app后端设计(3)--短信,邮件,推送服务 app后端设计(4)-- 通讯的安全性 app后端设计( ...

  2. app后端设计--总目录

    做了3年app相关的系统架构,api设计,先后在3个创业公司中工作,经历过手机网页端,android客户端,iphone客户端,现就职于app云后端平台bmob(想了解bmob点击这里).其中的乐与苦 ...

  3. app后端设计(0)--总文件夹

    原文:http://blog.csdn.net/newjueqi/article/details/19003775 做了接近两年app相关的系统架构,api设计,先后在两个创业公司中工作,经历过手机网 ...

  4. [置顶] app后端设计--总目录

    版权声明:本文为博主原创文章,未经博主允许不得转载. 做了3年app相关的系统架构,api设计,先后在3个创业公司中工作,经历过手机网页端,Android客户端,iphone客户端,现就职于app云后 ...

  5. app后端设计(0)--总目录(转)

    原文:http://blog.csdn.net/newjueqi/article/details/19003775 做了接近两年app相关的系统架构,api设计,先后在两个创业公司中工作,经历过手机网 ...

  6. app后端设计(php)

    来源:http://blog.csdn.net/column/details/mobilebackend.html?page=1 做了3年app相关的系统架构,api设计,先后在3个创业公司中工作,经 ...

  7. app后端设计(12)--图片的处理

    app上线后,不断接受用户的反馈,于是,反馈非常差的情况下,都会有app的改版. 一旦app的改版,都会有比较大的UI改动,一改动UI,那么图片的尺寸也就必须要改变. 在app后端设计(1)—api( ...

  8. MySQL数据库分表的3种方法

    原文地址:MySQL数据库分表的3种方法作者:dreamboycx 一,先说一下为什么要分表 当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目 ...

  9. zabbix 数据库分表操作

    近期zabbix数据库占用的io高,在页面查看图形很慢,而且数据表已经很大,将采用把数据库的数据目录移到新的磁盘,将几个大表进行分表操作 一.数据迁移: 1.数据同步到新的磁盘上,先停止mysql(不 ...

随机推荐

  1. XShell中文乱码问题解决

    现象:XShell终端中输入中文显示乱码 原因:XShell终端的编码格式与服务器不同 解决:修改XShell终端的编码格式:菜单中点击,文件->属性->终端->编码,选择“UTF- ...

  2. 如何取消mysql的密码?

    有两种方法: 1.mysql命令 SET PASSWORD FOR root@localhost=PASSWORD(''); 2.运行  mysqladmin 命令 mysqladmin -u roo ...

  3. 51nod 1673 树有几多愁(链表维护树形DP+状压DP)

    题意 lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输出 ...

  4. We Need More Bosses CodeForces - 1000E(缩点 建图 求桥 求直径)

    题意: 就是求桥最多的一条路 解析: 先求连通分量的个数 然后缩点建图  求直径即可 #include <bits/stdc++.h> #define mem(a, b) memset(a ...

  5. Firefox download 乱码问题。

    import javax.mail.internet.MimeUtility; fileName = MimeUtility.encodeWord ( fileName ); response.add ...

  6. 【题解】 [SDOI2009] Elaxia的路线(最短路+拓扑排序)

    懒得复制,戳我戳我 Solution: 题目大概意思就是找两条最短路后,找出最长公共部分 我们就只用以四个点为源点开始走\(SPFA\),然后我们就只用遍历每条边然后建立一个新的拓扑图,然后随便搞一下 ...

  7. BZOJ 2879 [Noi2012]美食节 | 费用流 动态开点

    这道题就是"修车"的数据加强版--但是数据范围扩大了好多,应对方法是"动态开点". 首先先把"所有厨师做的倒数第一道菜"和所有菜连边,然后跑 ...

  8. 二、spring boot 1.5.4 异常控制

    spring boot 已经做了统一的异常处理,下面看看如何自定义处理异常 1.错误码页面映射 1.1静态页面 必须配置在 resources/static/error文件夹下,以错误码命名 下面是4 ...

  9. Openstack 错误日志查看方法

    openstack错误日志查看方法 https://blog.csdn.net/ZanShichun/article/details/72672945

  10. k8s如何管理Pod(rc、rs、deployment)

    是豆荚,可以把容器想像成豆荚里的豆子,把一个或多个关系紧密的豆子包在一起就是豆荚(一个Pod).在k8s中我们不会直接操作容器,而是把容器包装成Pod再进行管理(关于Pod,大家可以参考第十期的分享“ ...