分库和分表基本概念

概述

单体架构应用:
项目初期,用户量不大时,往往是使用单体应用架构,所有应用代码都打成一个包发布、所有数据都存储在一个数据库中。

随着业务的发展,数据量、访问量增加,经过单体架构的sql优化、索引优化、缓存优化、数据库参数优化等优化手段都用完了,还是没能达到理想的效果时,就需要对数据库进行拆分。

分库

分库就是把原本All in one的数据库按照一定的维度进行数据库的拆分,比如一个电商系统,原本是用户相关表、订单相关表、库存相关表、优惠相关表都是在同一个数据库中,现在要按照这些维度进行拆分。
拆分前:
在这里插入图片描述
拆分后:
在这里插入图片描述
这样拆分称为分库,是为了减少单库的压力。

分表

当数据量达到一定规模后,分库往往也无法达到预期的性能要求,此时就需要对数据进行分表。
分表通常有两种类型:垂直分表和水平分表

垂直分表

垂直切分是基于表字段安装一定业务逻辑进行划分的,拆分成不同的表,表结构往往是不一样的。
在这里插入图片描述
比如对一个商户信息表拆分成若干个表,然后用一个商户编号进行关联,这种就是表的垂直拆分,避免一个数据表太多字段。
在这里插入图片描述

水平分表

当数据量是在太大 达到单表2000万,此时无论怎么垂直拆,都不好解决性能问题,就需要水平分表。
水平分表就是按照一定的规则,比如日期、对id进行取模、对id进行分段、对某个规则字段进行分段、地区等等规则,对同一个表的数据进行拆分,这些表的表结构一模一样,只是数据不一样,对数据进行了分片,跟redis的集群分片相似。这些拆分的表可以分配在同一个库,也可以在不同库。比如原本2000万数据,进行分成10个表,就是每个表200w,大大减少了数据库的单表压力。

在这里插入图片描述

分库分表带来的问题:

分库分表是解决庞大数据和访问量一种有效的方式,但是也会带来相应的问题:

  1. 跨库关联查询,比如如果要查询合同信息的时候,要关联用户信息,但是由于进行了分库分表,所以不能直接像单库那样join连接查询,这里有几种解决方案(主要是概述,具体操作要看其他文章):
  • 字段冗余,比如查询合同信息表要关联查询用户信息表的用户名、电话号码,就把这两个字段冗余到合同信息表中,然后直接单表查询就能查询到相应信息,不用跨库关联查询了。
  • 数据同步:比如商户系统要查询产品系统的产品表,我们干脆在商户系统数据库中创建一张产品表,通过ETL或者其他方式定时同步数据。
  • 全局表:比如一些表再大多数系统中都用到,并且该表的数据的变化频率比较小,比如字典表,就可以在所有系统数据库中冗余这些表数据,这些表叫作全局表,然后修改时就做一些同步操作。
  • ER表(绑定表):我们有些表是存在主外键关系的,比如订单表和订单明细表,有从属关系,在我们水平分表时,如果父表的数据与子表对应的数据被分配在不同的库,就会产生跨库关联的不必要麻烦,如果把对应数据存储在同一个库,就避免这个麻烦,比如订单表跟订单明细表是一对多的关系,我们就可以把订单id为1的订单表记录和订单明细表中,订单id为1的记录落库在同一个库中,此称为绑定表。
  • 如果实在无法避免跨库关联查询,那就先查询A表数据,再查询B表数据,然后在应用层手动进行数据组装。
  1. 分布式事务问题,在不同库中维持同一个事务,就是分布式事务。
  2. 排序、翻页、函数计算问题:跨多节点进行查询时,会出现limit分页,order by 排序、函数计算等问题,比如节点1某表有id为1、3、5、7、9,节点2这个表有id为2、4、6、8、10数据。
    使用sql:select *from xxx order by id limit 5.此时就要先在两个节点分别使用该查询语句查出5条数据,然后在应用层再进行排序,决定出最后返回的5条数据。

max、min、sum、count 之类的函数在进行计算的时候,也需要先在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总和再次计算,最终将结果返回。

  1. 全局主键避重问题,Mysql有自增主键,Oracle也有Sequence序列,如果仅仅是一个数据库,那么可以保证id不重复,但是水平分表后,每个数据库都有自己的增长规律,肯定会出现id重复问题,这个时候我们就不能使用本地自增方式了。
    解决方案:
  • UUID:是主键最简单的方案,本地生成,性能高,没有网络耗时,但是UUID非常长,会占用大量存储空间,并且作为主键索引和基于索引进行查询时也会存在性能问题,在InnoDB中,由于UUID是无序的,所以会导致数据位置频繁变动,导致分页。
  • 把序号维护在数据库的一张表中,这张表记录了全局位数的类型、位数、起始值,当前值,当其他应用新增数据时,先到这里锁行更新获得id,然后在进行插入,但是并发性能差。
  • redis:基于redis INT原子自增的特性,使用批量的方式降低数据库写压力,每次获取一段区间ID号,用完之后再去数据库获取,可以大大减轻数据库压力。
  • 雪花算法。
  1. 多数据源问题:可以在应用层实现、代理层实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值