# (一)什么是分库分表 {#一-什么是分库分表}
分库分表故名思意是将一张表拆分成多个表,可能是一个库中的分表,也可能是分库又分表。分库分表主要解决的问题是数据库的性能瓶颈问题。即使建立索引,当数据量超过一定值时,查询效率就注定会降下来。通过分库分表,可以将原本的大数据拆分到多个表或者库中。
但是分库分表并非是很优的方式,在不需要分库分表的情况下,尽量不要盲目去拆分数据库,也不要过度拆分数据库。
# (二)分库分表方式 {#二-分库分表方式}
# 2.1 横向拆分 {#_2-1-横向拆分}
这种拆分方式往往用于数据量庞大的表,是对数据的切割, 比如一个表中有4000万条数据,即使建立了索引,也会导致IO次数增加,查询效率低的问题。这个时候,我们就可以把这张4000万数据的表拆分成4张1000万条数据的表。
# 2.2 纵向拆分 {#_2-2-纵向拆分}
纵向拆分往往是基于业务的拆分,纵向分表是将一个表按照字段拆分成多张表,每个表存储其中的一部分字段。
比如我们做一个电商系统,原来在商品表里存放了商品的基本信息和详细描述,但是在实际使用时,商品详细描述只有在用户点进商品里面时才需要,因此我们可以将他单独拆分出来。
# (三)分库分表的问题 {#三-分库分表的问题}
在没有必要拆分的情况下,不建议做分库分表的操作,因为分库分表会带来一些问题,比如:
# 1、横向拆分的主键问题: {#_1、横向拆分的主键问题}
横向拆分时将数据分到了多个库或者多个表中,那么查询或者新增时,必须要确保能准确定位到该数据主键所在的位置。
# 2、纵向拆分的join问题: {#_2、纵向拆分的join问题}
纵向拆分时,我们按字段把表分成了多个,但是当需要用到数据时,不可避免就需要多表join进行查询。
# 3、分页查询问题: {#_3、分页查询问题}
当我们把数据拆分到多张表,然后又需要按照某种条件排序分页查询时,这个操作就会很麻烦。比如,我要按时间排序分页查询所有数据,你就要把每个表的数据都拿出来,在内存中做一层排序,再返回给接口调用方。
# 4、去重函数 {#_4、去重函数}
单表时,通过distinct就可以把重复的数据去掉,但是如果数据保存在多张表,这些函数就很难操作了。同样的道理还可以用在group分组、sum函数等等。
除此之外,分库分表还可能导致很多其他问题。
# (四)分库分表的组件 {#四-分库分表的组件}
既然分库分表有那么多问题,但是我们又不得不去分库,有什么其他办法呢?一些组件可以帮我们让分库分表变得更加方便和高效。
现在主流的有京东数科的shardingsphere ,Mycat 、Tddl 等等。shardingsphere目前已经是Apache的顶级项目,目前看来是最值得使用的组件。
# (五)总结 {#五-总结}
本文对分库分表的一些基本概念和问题进行了讲解,不管是分库还是分表,在真实的场景下一定要做好技术储备以及合理的拆分方案。接下来我会发表几篇关于分库分表组件shardingsphere的使用,我是Java鱼仔,我们下期再见!