前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mysql分库分表(1) --- 概念篇

Mysql分库分表(1) --- 概念篇

作者头像
创译科技
发布2019-10-24 16:02:54
9640
发布2019-10-24 16:02:54
举报
文章被收录于专栏:Node开发Node开发

前两篇文章重点讲到了Mysql数据库的主从同步和读写分离,使用主从同步实现从数据库从主数据同步数据保持主从数据一致性,读写分离使用主数据库负责写操作,多个从数据库负责读操作,由于从库可以进行拓展,所以处理更多的读请求也没问题。但是如果业务比较多,写请求越来越多要如何处理呢?可能有人说我可以再加一个master分担写操作,但是两个master数据肯定是需要同步的,主主同步 + 主从同步很显然会让我们的系统架构变得更为的复杂。所以本篇文章主要讨论一个对写操作进行切分的技术:分库分表。

我们都知道,在业务量不多的时候,单库单表完全可以支持我们的应用。但是随着业务的逐渐发展,如果使用单库单表是存在几个弊端的:

  • 随着数据量的增大,数据库性能会有所下降。一般来说单表合适存放1000w条数据以下。
  • 如果写请求居多,使用单台master会导致所有写请求都访问该服务,肯定会导致master性能大幅度下降。
  • 如果所有表全部存放在同一个数据库,在高并发的情况下所有业务都连接同一个数据库,由于连接的数量稀少会导致并发的上限。

而分库分表的方式一般有两种:垂直拆分和水平拆分。接下来我们可以分别看看这两种分库分表方式:

垂直拆分

垂直拆分主要有两种:垂直分库和垂直分表。

垂直分库:

垂直分库其实逻辑上会更容易理解,比如目前我数据库有用户相关的表如用户表,积分表,实名认证表,还有订单相关的比如商品表,拼团表,还有商品相关的商品表。如果全部表全部放在同一个数据库,由于数据库连接的匮乏以及磁盘IO等影响,所以性能肯定会收到一定的影响。这时候我们可以可以将用户相关的放在user数据库,商品相关的放在goods数据库,订单相关的放在order数据库。然后不同的数据库存放在不同的服务器上,这样还可以避免因为用户量越来越多导致数据库性能受到服务器瓶颈的影响。所以说分库实际上就是在多个服务器搭建多个不同的数据库,然后按照不同的业务逻辑将不同的表存放在不同的数据库。

垂直分表:

垂直分表主要是表中数据列成百上千的数据表使用的,使用的方案是创建辅助表,将表中数据量较大或者不常用的数据库移动到辅助表,常用的字段留在原表中,这样就可以避免我们在查询大表的时候由于不常用的大字段影响查询的性能。

水平拆分

水平拆分也有两种:水平分表和水平分库分表。

水平分表:

水平分表和垂直分表区别在于垂直分表针对的是列,将不常用的列拆分到辅助表。而水平分表针对的是表,在同一个数据库中创建多张一样的表,比如我们在order数据库中创建三张订单表order1order2order3,然后插入订单时将id3取余,根据不同的值存入不同的订单表,但是由于水平分表是将数据表存放在同一个数据库,水平分表可以降低单标的数据量,有助于提高查询效率。如果业务量很大一样会受到服务器IO的瓶颈,所以我们一般更经常使用的还是水平分库分表。

水平分库分表:

水平分库分表实际上就是在多台不同的机器分别创建数据库和数据表,比如订单表我们可以在三台不同的机器上分别创建order数据库和order数据表,然后根据一定的逻辑将不同的数据存放到不同机器的数据库中。一般来说水平分库分表主要有以下几种拆分规则:

  • 范围拆分:比如订单表通过id拆分,id1100000在服务器aorder数据库,id100001200000存放在服务器border数据库,以此类推。
  • 地理拆分:将订单表按照不同地区将表中的数据拆分到不同服务器的order数据库中存储。比如可以按照省份来进行拆分。
  • 取模拆分:取模就是刚才水平分表讲到的比如有三个订单表,可以将id3取余,但是区别在于水平分库分表是将同样的数据库和数据表存放在不同机器,所以说可以有效缓解单机瓶颈问题。
  • 时间拆分:根据时间来拆分表中的数据,可以将表中创建时间超过一年的数据拆分到其他数据库的order数据库存储,原表中只保留被查询概率较高的数据,而这部分数据往往都是近期才创建的,所以可以通过时间拆分实现冷热数据分离。

分区

分区是什么意思呢?分区实际上是指同一个数据表中不同行的数据记录到不同的分区中,每个分区都有一个.idb文件,所以说分区可以帮助我们将一个数据表拆分成几个更小的部分。Mysql只支持局部索引分区不支持全局分区,mysql每一个分区既保存了数据,又存放了索引。MySQL分区主要分为以下几种:

  • RANGE分区:RANGE分区主要用于日期列的分区,是基于连续区间的列值来进行分区的。RANGE分区也是最常用的分区方式。
  • LIST分区:LIST分区列的值是散列的,也正是由于分区列的值是散列的所以需要手动定义分区列的值。
  • HASH分区:HASH分区就是通过自定义算法将数据均匀分布到不同分区,保证所有分区中数据大致相同。HASH分区只支持整数分区。
  • KEY分区:key分区使用数据库自带函数进行分区。KEY分区可支持BLOBTEXT列之外的数据列分区。

分区注意点

分区主要注意一点,如果要分区的表有主键或唯一键,则分区表的主键/唯一键必须包含分区键。分区的意义在于将一张大表根据分区条件分割成几个小表,但是对于数据来说仍然是一张表,可以改善大表的可伸缩性,可管理性,还可以提高数据库的效率。

分区的优点

  • 与数据存放在单个磁盘相比,可以存储更多的数据。
  • 对于那些已经失效的数据,通常可以通过删除对应的分区,来实现删除数据,这样比delete效率更高。
  • 一些查询可以得到极大的优化,满足一个给定WHERE语句的数据可以只保存在一个分区内,这样在查找时就不用查找其他剩余的分区。
  • 涉及聚合函数的查询,可以进行并行处理。意味着聚合函数查询可以在每个分区上同时进行,最终结果只需通过总计所有分区得到的结果。

分库分表产生的问题

分库分表可以一定程度去除数据库的瓶颈,但是不可避免的分库分表会带来一部分问题,分库分表主要有两个问题:联表查询join操作困难和分布式事务的问题。

联表查询

我们一开始单库多表的情况下使用join联表操作是非常简单的,使用一条简单的sql语句配上join就可以得到我们需要的结果,但是分库之后我们可能一次查询无法完成,我们可能需要先去服务器a查询用户信息,再去服务器b, c, d分别查询订单信息才能完成我们的联表查询功能,联表查询功能我觉得比较适合的一个逻辑是分别查询出我们需要的数据,然后代码方面在service层负责组装所有数据,最后再返还给客户端,这样虽然比较复杂,但是数据库的性能可以得到最大化。

分布式事务

进行分库操作之后,事务操作就变成分布式事务了,而之前在谈Redis的时候特提到过分布式,我们都知道涉及到分布式逻辑都是比较复杂的,而且如果使用Mysql自带的分布式事务管理功能会导致性能大大降低,大概是单库的一成左右性能,所以方案一般有两种:使用分布式事务中间件比如Mycat或者在代码中业务逻辑进行控制,不过如果在代码中控制,可能会使系统更加复杂,可维护性比较低。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿周先森 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档