简介分库分表
# 简介分库分表
本文说的分库分表,以及后续说的分库分表实现技术都是基于MySql。
# 诞生原因
分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题。将原来独立的数据库--》拆分成若干数据库组成 ,将数据大表拆分成--》若干数据表组成,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。
- 为什么不选择通过修改表结构、或者增加索引,或者提高硬件性能的方式提高数据库性能?
因为:通过提升服务器硬件能力来提高数据处理能力,比如增加存储容量、CPU等,这种方案成本很高,并且如果瓶颈在MySQL本身那么提高硬件也是有很的。
因为:已经修改过表结构、增加过对应索引了。面对庞大的数据,此时这些手段已经没什么效果了。
面对此时庞大的数据,最有效的解决方式,此刻就是分库分表
。
# 分的方式
# 垂直分
# 垂直分表
在数据库设计中,垂直分表(也称为垂直分区)是指将一个大表按照列的方向拆分成多个小表。每个新表包含原表的一部分列,但所有表共享相同的主键或唯一标识符。通过这种方式,可以减少单个表的宽度(即列的数量),从而优化查询性能和管理复杂度。
- 这样做为什么能提升性能?对于抽离出来的列有什么条件吗?还是说随机抽取?
抽离出来的列通常是经常查询的。如此一来,因为查询时只用对小表select,只涉及部分字段的查询,可以显著减少 I/O 和内存使用,提高查询速度。
因为进行了分表,所以有些字段的更新,不会影响其他字段的查询,因为它们现在是不同的表了,这样也能提高查询的效率,不会受到因为更新,mysql会使用锁的影响了。同时一定程度上避免了,因为大字段(text,blob)可以跟常用查询表分开了,避免了大字段带来的IO低效率。
为什么大字段Io效率低:第一是由于数据量本身大,需要更长的读取时间;第二是跨页,页是数据库存储单位,很多查找及定位操作都是以页为单位,单页内的数据行越多数据库整体性能越好,而大字段占用空间大,单页内存储行数少,因此Io效率较低。第三,数据库以行单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘Io,从而提升了数据库性能。
扩展:
- 可以针对不同的表进行独立的备份和恢复操作,提高灵活性。
最后总结下优劣:
1.为了避免I0争抢并减少锁表的几率,查看详情的用户与商品信息浏览互不影响
2.充分发挥热门数据的操作效率,商品信息的操作的高效率不会被商品描述的低效率所拖累
但请一定记住,新技术的引入一定会带来新的问题,垂直分表也会带来如下的问题:
- 关联查询开销:如果经常需要联合多个表来获取完整数据,可能会增加查询复杂性和执行时间。因此,应根据实际需求权衡是否进行垂直分表。
- 事务管理:在跨多个表的事务中,确保一致性更加复杂,特别是在分布式环境中。
- 应用层逻辑:应用程序代码需要相应调整,以处理多个表之间的关系和查询逻辑。
# 垂直分库
定义:垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用。
比如:之前的分表数据还是始终限制在一台服务器,库内垂直分表只解决了单一表数据量过大的问题,但没有将表分布到不同的服务器上,因此每个 表还是竞争同一个物理机的CPU、内存、网络IO、磁盘。
经过思考,他把原有的SELLER_DB(卖家库),分为了PRODUCT_DB(商品库)和STORE_DB(店铺库),并把这两个库分散到不同服务器。
它带来的提升,主要是以下几点:
- 解决业务层面的耦合,业务清晰
- 因为现在某些业务是专库专用了,所以可以自由地对不同业务的数据进行分级管理、维护、监控、扩展等
- 高并发场景下,垂直分库一定程度的提升I0、数据库连接数、降低单机硬件资源的瓶颈
它带来新的便利的同时,也会引入新的挑战或者说是缺点:
- 复杂的应用层逻辑:
- 应用程序需要处理多个数据库实例之间的连接和查询逻辑,增加了开发和维护的复杂度。
- 特别是在需要跨多个数据库实例执行联合查询时,可能需要额外的逻辑来整合数据。
- 分布式事务管理:
- 如果某些操作涉及多个数据库实例,需要使用分布式事务管理机制(如两阶段提交),这会增加系统的复杂性和潜在的性能开销。
- 数据一致性挑战:
- 在分布式环境中,确保数据的一致性变得更加复杂,特别是在需要跨多个数据库实例更新数据时。
- 可能需要引入额外的技术或工具来保证最终一致性(如消息队列、事件驱动架构)。
- 初始设置和维护成本:
- 设置和维护多个数据库实例的成本较高,包括硬件资源、监控工具、备份和恢复策略等。
- 需要更多的运维人员和技术支持来管理和优化多个数据库实例。
# 水平分
# 水平分库
定义:水平分库是把同一个表的数据按一定规则拆到不同的数据库中,但分出来的数据结构跟原来的是相同的。每个库可以放在不同的服务器上。
比如:你某张表有1w条数据,你把其中5000条数据,分出来,划分规则是id的奇偶性,然后再把分出来的数据放到另一个库,这就是水平分库。
垂直分库的分,会改变原有表的结构。
优劣:
它的优:跟上文中的类似提高了执行效率。
但劣势也一样,增加了复杂性,比如因为增加了数据库实例,势必会增加运维的工作。
# 水平分表
水平分表的思路跟水平分库的思路相同,取出一部分数据(按照一定规则),但结构相同,放到另一张表中,且新表跟原来的表在同一个数据库实例中。
总结下:水平分表就是将一个大表的数据按照某些条件拆分成多个较小的表,每个新表包含原表的一部分行。这些新表通常被称为“分片”(shard)。
有了水平分的方式,理论上你是可以无限分表分库的,它不像垂直分有业务限制,因为它的核心思想是:取出一部分数据,放到另一个地方。
# 总结
垂直分表:可以把一个宽表的字段按访问频次、是否是大字段的原则拆分为多个表,这样既能使业务清晰,还能提升部分性能。拆分后,尽量从业务角度避免联查,否则性能方面将得不偿失。
垂直分库:可以把多个表按业务耦合松紧归类,分别存放在不同的库,这些库可以分布在不同服务器,从而使访问压力被多服务器负载,大大提升性能,同时能提高整体架构的业务清晰度,不同的业务库可根据自身情况定制优化方案。但是它需要解决跨库带来的所有复杂问题。
水平分库:可以把一个表的数据(按数据行)分到多个不同的库,每个库只有这个表的部分数据,这些库可以分布在不同服务器,从而使访问压力被多服务器负载,大大提升性能。它不仅需要解决跨库带来的所有复杂问题,还要解决数据路由的问题(数据路由问题后边介绍)。
水平分表:可以把一个表的数据(按数据行)分到多个同一个数据库的多张表中,每个表只有这个表的部分数据,这样做能小幅提升性能,它仅仅作为水平分库的一个补充优化。
一般来说,在系统设计阶段就应该根据业务耦合松紧来确定垂直分库,垂直分表方案,在数据量及访问压力不是特别大的情况,首先考虑缓存、读写分离、索引技术等方案。若数据量极大,且持续增长,再考虑水平分库水平分表方案。
# 公共表
在进行数据库的分库分表(Sharding)时,某些表可能需要被所有分片共享,这些表被称为“公共表”或“全局表”。公共表通常包含一些不随业务数据变化而频繁更新的信息,或者是用于跨分片查询和关联的数据。合理地管理和使用公共表可以简化查询逻辑、提高性能,并确保数据的一致性。
这些表该使用的时候,如何选择,或者更新也是一个问题。
以下是一些常见的公共表类型
- 字典表:存储各种枚举值、状态码、类型定义等,如订单状态、支付方式、商品类别等。
- 配置表:存储系统配置参数,如应用设置、权限控制、API 密钥等。
- 区域信息表:包含地理信息,如国家、省份、城市等,用于地址解析、物流配送等场景。
公共表:在分库分表架构中,公共表是指那些需要被所有分片共享的表,通常包含全局唯一且较少变动的数据。
# 带来的问题
# 事务一致性问题
分布式事务问题。由于分库分表把数据分布在不同库甚至不同服务器,不可避免会带来
# 跨节点关联查询
在没有分库前,我们检索商品时可以直接通过连表查询,但分开后,可能需要通过多次分步查询来实现。
# 跨节点分页、排序函数
跨节点多库进行查询时,limit分页、order by排序等问题,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序。
# 主键避重
在分库分表环境中,由于表中数据同时存在不同数据库中,主键值平时使用的自增长将无用武之地,某个分区数据库生成的ID无法保证全局唯一。因此需要单独设计全局主键,以避免跨库主键重复问题。