当一张表的数据达到几千万时,查询一次所花的时间会变长。这时候,如果有联合查询的话,可能会卡死在那儿,甚至把系统给拖垮。

而分库分表的目的就在于此:减小数据库的负担,提高数据库的效率,缩短查询时间。另外,因为分库分表这种改造是可控的,底层还是基于RDBMS,因此整个数据库的运维体系以及相关基础设施都是可重用的。

目前我们系统将近20亿数据,每张表最大的接近600w条/表,每条数据大约3k,每个表将近1.5G的数据。查询经常超时,单条SQL执行count(*)查询时间达到了最大260ms,0.26s(标准是超过0.1s的数据为慢SQL)。

为了说明我们为什么要分库分表,我们看一下sql的执行过程。

mysql执行一条sql的过程如下:

1、收到sql

2、把sql放到排队队列中

3、执行sql

4、返回结果

在这个执行过程中最花时间的地方在于:

1.排队等待的时间,

2.sql的执行时间。

如果有2个sql都要同时修改同一张表的同一条数据,mysql对这种情况的处理是:一种是表锁定(MyISAM存储引擎),一个是行锁定(InnoDB存储引擎)。

表锁定表示其他操作都不能对这张表进行操作,必须等当前对表的操作完才行。行锁定也一样,别的sql必须等这条数据操作完了,其他人才能对这条数据进行操作。

如果数据太多,一次执行的时间太长,等待的时间就越长,这也是我们为什么要分表的原因。

分库分表术语:

读写分离: 不同的数据库,同步相同的数据,分别只负责数据的读和写;

分区:指定分区列表达式,把记录拆分到不同的区域中(必须是同一服务器,可以是不同硬盘),应用看来还是同一张表,没有变化;

分库:一个系统的多张数据表,存储到多个数据库实例中;

分表: 对于一张多行(记录)多列(字段)的二维数据表,又分两种情形:

垂直分表: 竖向切分,不同分表存储不同的字段,可以把不常用或者大容量、或者不同业务的字段拆分出去;水平分表(最复杂): 横向切分,按照特定分片算法,不同分表存储不同的记录。在实际生产中,通常的进化过程是:单库单表->单库多表->多库多表;;分区->分表->分库(垂直分库 - 水平分库 - 读写分离)

单库单表

单库单表是最常见的数据库设计,例如,有一张订单表(order)放在数据库中,所有的订单都可以在order表中查到。

单库多表

随着订单数量的增加,order表的数据量会越来越大,当数据量达到一定程度的时候,对order表的查询会变慢,从而影响整个DB的性能。

另外,随着需求的迭代,如果增加添加一列的时候,mysql会锁表,期间所有的读写操作只能等待,别无他法。

这时候,可以将order进行水平的切分,产生多个表结构完全一样的order表。比如:order_01,order_02....,order_n,那么order_01+order_02+order_n的数据是一份完整的订单数据。

这个水平切分,简单的做法如:

按数量切分,1~1000的存在第一张表,1001~2000存在第二张表;

按时间切分,比如:2019年1月份存在第一张表,2019年2月份存在第二张表;还可以按照id的哈希值进行切分,等等等等

多库多表

随着数据量增加,单台数据库的硬件存储不够了,并且,随着查询量的增加,单台数据库服务器已经没办法支撑。这时候就需要对数据库进行水平区分。

比如按地区分库,一个省份在一个物理数据库等等

任何事情都有两面性,分库分表也不例外,如果采用分库分表,会引入新的的问题

1.分布式事务问题

做了垂直分库或者水平分库以后,就必然会涉及到跨库执行SQL的问题,就会引发互联网界的老大难问题-"分布式事务"。那么要如何解决这个问题呢?

使用分布式事务中间件使用MySQL自带的针对跨库的事务一致性方案(XA),不过性能要比单库的慢10倍左右。能否避免掉跨库操作(比如将用户和商品放在同一个库中)2.跨库join的问题

分库分表后,表之间的关联操作将受到限制,就无法join位于不同分库的表,也无法join分表粒度不同的表, 结果原本一次查询能够完成的业务,可能需要多次查询才能完成。

那么要如何解决这个问题呢?

简单的解决方法:

全局表:基础数据,所有库都拷贝一份。字段冗余:把需要join的字段冗余在各个表中,这样有些字段就不用join去查询了。系统层组装:应用端先分别查询出所有复核条件的,然后在应用端组装起来,类似于一个mapreduce的过程(较复杂)。3.横向扩容的问题

当我们使用哈希取模做分表的时候,针对数据量的递增,可能需要动态的增加表,此时就需要考虑数据迁移的问题。

原来使用的是hash后对8进行取模,那么,数据是均分在8个表(库)上。

如果8个表不够的时候,我们要扩展到16个表,这时候,我们hash后对16取模,新数据是没有问题的,旧数据就会发生错乱。

如果哈希后是9,那么,原来我们对8取模后,是1,会到表1进行查询;但是,现在我们是对16取模,那么是到表9进行查询的,而这个数据在表9又不存在,因此,就会找不到数据了

4.结果集合并、排序的问题

因为我们是将数据分散存储到不同的库、表里的,当我们查询指定数据列表时,数据来源于不同的子库或者子表,就必然会引发结果集合并、排序的问题。

如果每次查询都需要排序、合并等操作,性能肯定会受非常大的影响。

上面列出了分库分表的常见的一些,总的来说:

能不切分尽量不要切分,如果没有达到几百万,通常无需分库分表如果一定要切分,一定要选择合适的切分规则,提前规划好。如果一定要切分,尽量通过数据冗余或表分组来降低跨库 Join 的可能。对于现在市面上有好几种数据库中间件,这些中间件对数据 Join 实现,个中滋味,只能自己体会。业务读取尽量少使用多表 Join。数据尽可能的比较均匀分布数据到各个节点上

mysql为什么要分库_我们为什么要分库分表相关推荐

  1. 阿里云 mysql 分表分库_阿里云DRDS分库分表

    以下大部分内容非原创,整理自阿里云官方文档 单库单表 建一张单库单表,不做任何拆分. CREATE TABLE single_tbl( id int, name varchar(30), primar ...

  2. mysql分表组件_利用Sharding-Jdbc组件实现分表

    看到了当当开源的Sharding-JDBC组件,它可以在几乎不修改代码的情况下完成分库分表的实现.摘抄其中一段介绍: Sharding-JDBC直接封装JDBC API,可以理解为增强版的JDBC驱动 ...

  3. 冷热分离和直接使用大数据库_用读写分离与分表分库解决高访问量和大数据量...

    原标题:用读写分离与分表分库解决高访问量和大数据量 一. 数据切分 关系型数据库本身比较容易成为系统瓶颈,单机存储容量.连接数.处理能力都有限.当单表的数据量达到1000W或100G以后,由于查询维度 ...

  4. mysql 分表分库mycat_Mysql数据库之如何Mycat分表分库?

    Mycat分表分库虽然能解决大表对数据库系统的压力,但也有一些不利,因此Mycat分表分库要先解决的问题是,分不分库,分哪些库,什么规则分,分多少分片.那么究竟是怎么分的呢? 1.能不分就不分,100 ...

  5. 两个表点击分页的时候怎么判断点的是哪一个表_百亿级数据分表后怎么分页查询?...

    当业务规模达到一定规模之后,像淘宝日订单量在5000万单以上,美团3000万单以上.数据库面对海量的数据压力,分库分表就是必须进行的操作了.而分库分表之后一些常规的查询可能都会产生问题,最常见的就是比 ...

  6. mysql为什么不驼峰_为什么不用驼峰命名创建表名和字段?

    其实,这是一种规范,而不是一种规则.所以你使用驼峰来命名也是可以的,但是我们要避免用驼峰来命名. 不只是数据库,就是平常的程序也是,因为: MYSQL 5.7 FEATURES. THIS MANUA ...

  7. mysql树状数据结构_树状结构的数据表如何设计?

    使用Modified Preorder Tree简直是必须的.网上可以搜一下modified preorder tree travesal找到相关资料.参考 http://www.sitepoint. ...

  8. mysql分库分表风险_数据库分库分表存在的问题及解决方案

    读写分离分散了数据库读写操作的压力,但是没有分散存储压力,当数据库的数据量达到千万甚至上亿条的时候,单台数据库服务器的存储能力就会达到瓶颈,主要体现在以下几个方面: 数据量太大,读写性能会下降,即使有 ...

  9. 当当网mysql分库分表策略_当当开源sharding-jdbc,轻量级数据库分库分表中间件

    近期,当当开源了数据库分库分表中间件sharding-jdbc. Sharding-JDBC是当当应用框架ddframe中,从关系型数据库模块dd-rdb中分离出来的数据库水平分片框架,实现透明化数据 ...

最新文章

  1. 【Linux】Linux简单操作之安装jdk
  2. fragment+viepager 的简单暴力的切换方式
  3. xp下安装redmine 2.4.3
  4. python分布式爬虫系统_如何构建一个分布式爬虫:理论篇
  5. php url标准化,seo优化教程:链接url标准化操作?
  6. DOM学习之路--Mr.Ember
  7. 你所不知道的程序员,不要再尬黑了
  8. 2008年12月信息处理技术员上午试卷 51CTO版参考答案
  9. 基于C#语言的可编程表达式计算器设计
  10. C# socket编程TcpClient与TcpListener UdpClient
  11. 25. 自定义Git
  12. ICCV2019 | 锁定视频中的目标:港大提出运动注意力检测方法
  13. 您的Mac已成功加入Wi-Di网络,但是无法访问互联网问题及解决方案
  14. 使用FFMpeg 提取MKV文件中的字幕
  15. (三万字长文)面试redis缓存大全!
  16. VUE定时器任务(每天定时12点执行)
  17. 【解惑】女生适合干计算机什么方面的工作
  18. 新年来到,特此制作一款烟花特效,预祝大家 虎虎生威,虎年大吉,生龙活虎
  19. Django REST 框架的 FBV 与 CBV 选择
  20. 调用百度人体关键点识别API

热门文章

  1. 1-3 数组的反序输出
  2. MySQL中实现分组排序
  3. DELPHI实现游戏内存的修改
  4. 安全专家呼吁希拉里要求重新计票
  5. python 之 collections
  6. 一款纯css3实现的响应式导航
  7. 如何快速在Linux系统的硬盘上创建大文件
  8. 合并单元格两行_Excel合并单元格的麻烦事你都经历了哪些?来一起远离那些麻烦事...
  9. python numpy 子数组_Python利用Numpy数组进行数据处理(一)
  10. 自由自在珍珠奶茶以市场细分来创新品牌