关系型数据库分库分表系列之一

发布时间:2022-06-26 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了关系型数据库分库分表系列之一脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

通常而言,MySQL数据库单表支持容量为1000万条记录,如果超过了这个量级,在查询/更新数据库表记录的时候,性能会受到很大的影响。在这种情况下,我们往往会采用其他的解决方案提高数据库读写性能:

  • 采用非关系型数据库如ElasticSeArch、Cassandra、HBase、Mongo等,非关系型数据库提供了原生的水平扩展方式,因此往往是海量数据存储的首选;
  • 对关系型数据库进行分库分表,使之能水平扩展;

本章主要讨论关系型数据库的分库分表方案。

基本概念

从拆分的维度来看,大致分为水平拆分和垂直拆分两种:

  垂直分布 水平分布
分表 对一个表而言,把部分访问频率比较低的列迁移到另外一个表中,拆分出来的表和原表的记录数量一致,但结构不同 将原表的部分记录按照一定规则放置到新表中,新表的结构和原表保持一致,但记录不同
分库 将数据库中的各个表按照业务进行拆分,使之分布到不同的数据库里 将水平拆分之后的表分散放置到不同的数据库中

从拆分的内容来看,可以分为两类:

  • 数据分片数据分片是将所有数据按照水平拆分的方式均匀分布到多个数据库/表中,每个数据库/表持有的数据都不一样;数据分片有助于数据库存储资和计算资源的负载均衡;
  • 主从备份主从备份分为热备和冷备,目的都是为了止数据的丢失;热备中主数据库和从数据库都持有相同数据的副本以保证数据库存储的高可用,并可以通过读写分离提高数据库的读性能;

分库分表的痛点

  • 事务性问题将原来的一个表/库进行拆分之后,就不能使用数据库自身的事务机制保证数据操作的ACID特性,因此需要利用分布式事务如基于两阶段提交的XA协议;
  • 联表查询的问题如果表A被拆分出了两个表A1和A2,表B被拆分出了两个表B1和B2,那么原来的A INNER JOIN B查询将需要(A1 INNER JOIN B1) UNION (A1 INNER JOIN B2) UNION (A2 INNER JOIN B1) UNION (A2 INNER JOIN B2)这样的操作;如果拆分得更多,最终的联表查询结果将是两个表拆分数量的笛卡尔积的Union操作,查询性能会变得异常低下;
  • 排序分页的问题对数据库表的查询结果进行排序分页,需要从各个分表查询出结果进行汇总之后再进行排序分页;

分库分表的架构

常用的分库分表架构大致可以分为两类:组件模式和代理模式;

  • 组件模式将分库分表的逻辑以组件的方式提供给客户端使用;客户端开发人员需要以依赖的形式引用这些组件,并在客户端代码中配置分库分表的规则;apache ShardingSphere、阿里巴巴的TDDL就是这类模式的代表;
  • 代理模式是在客户端和服务器之间加入一个代理服务器,这个代理服务器负责对客户端请求的数据进行分库分表,这些分库分表规则对客户端开发人员而言是完全透明的,它屏蔽了分库分表的复杂度,减轻了客户端开发人员的学习曲线;MyCat、Sharding Proxy是这类模式的代表。

由于代理模式加入了一个中间层,不像组件模式那样客户端直连数据库管理系统,因此性能相对较差;但由于组件模式需要客户端开发人员去了解分库分表的规则,并保证这些规则在客户端都能正确配置;因此代理模式渐渐成为分库分表架构设计的主流。

水平分表的方式

  • 顺序分布顺序分布又分为时间顺序主键顺序;时间顺序如将每年或每月的数据单独存储在一个表中;主键顺序如对于一个主键递增的表A,将主键ID为1-10000范围内的记录存储到A1表,将主键ID为10001-20000范围内的记录存储到A2表......以此类推。
  • Hash分布Hash分布可以分为三类:Hash取模一致性Hash虚拟槽分区;Hash取模是使用主键ID对数据库节点数量进行取模,得到的值即是该记录存储节点的索引值;一致性Hash和虚拟槽分区可以参考我以前写的Cassandra介绍中的数据分布部分。

脚本宝典总结

以上是脚本宝典为你收集整理的关系型数据库分库分表系列之一全部内容,希望文章能够帮你解决关系型数据库分库分表系列之一所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。