垂直分表
水平分表分的是行记录,而垂直分表,分的是列字段,它就像用一把刀,垂直的将一个表切成多张表一样。
垂直分表是基于列字段进行的。一般是表中的字段较多,或者有数据较大长度较长(比如text,blob,varchar(1000)以上的字段)的字段时,我们将不常用的,或者数据量大的字段拆分到“扩展表”上。这样避免查询时,数据量太大造成的“跨页”问题。
垂直分表的切分规则很好理解,一般是“不常用”或者“字段数据量大”这两点来做切割
分库
分库同样是为了应对超大数据带来的巨大的IO需求,如果不拆库,那么单库所能支持的吞吐能力和磁盘空间,就会成为制衡业务发展的瓶颈。
分库的主要目的是为突破单节点数据库服务器的I/O能力限制,解决数据库水平扩展性问题。
分库作用
分区和分表可以把单表分到不同的硬盘上,但不能分配到不同服务器上。一台机器的性能是有限制的,用分库可以解决单台服务器性能不够,或者成本过高问题。
将一个库分成多个库,并在多个服务器上部署,就可以突破单服务器的性能瓶颈,这是分库必要性的最主要原因。
分库的类型
分库同样分为水平分库和垂直分库。
水平分库
- 水平分库和水平分表相似,并且关系紧密,水平分库就是将单个库中的表作水平分表,然后将子表分别置于不同的子库当中,独立部署。
- 因为库中内容的主要载体是表,所以水平分库和水平分表基本上如影随形。
- 例如用户表,我们可以使用注册时间的范围来分表,将2020年注册的用户表usrtb2020部署在usrdata20中,2021年注册的用户表usrtb2021部署在usrdata21中。
垂直分库
- 同样的,垂直分库和垂直分表也十分类似,不过垂直分表拆分的是字段,而垂直分库,拆分的是表。
- 垂直分库是将一个库下的表作不同维度的分类,然后将其分配给不同子库的策略。
- 例如,我们可以将用户相关的表都放置在usrdata这个库中,将订单相关的表都放置在odrdata中,以此类推。
- 垂直分库的分类维度有很多,可以按照业务模块划分(用户/订单...),按照技术模块分(日志类库/图片类库...),或者空间,时间等等。
问题
事务问题。
- 问题描述:在执行分库分表之后,由于数据存储到了不同的库上,数据库事务管理出现了困难。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。
- 解决方法:利用分布式事务,协调不同库之间的数据原子性,一致性。
跨库跨表的join问题。
- 问题描述:在执行了分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上,这时,表的关联操作将受到限制,我们无法join位于不同分库的表,也无法join分表粒度不同的表,结果原本一次查询能够完成的业务,可能需要多次查询才能完成。
- 解决方法:tddl、MyCAT等都支持跨分片join。但是我们应该尽力避免跨库join,如果一定要整合数据,那么请在代码中多次查询完成。
额外的数据管理负担和数据运算压力。
- 问题描述:额外的数据管理负担,最显而易见的就是数据的定位问题和数据的增删改查的重复执行问题,这些都可以通过应用程序解决,但必然引起额外的逻辑运算,例如,对于一个记录用户成绩的用户数据表userTable,业务要求查出成绩最好的100位,在进行分表之前,只需一个order by语句就可以搞定,但是在进行分表之后,将需要n个order by语句,分别查出每一个分表的前100名用户数据,然后再对这些数据进行合并计算,才能得出结果。
- 解决方法:无解,这是水平拓展的代价。