简介
互联网系统需要处理大量用户的请求。比如微信日活用户破10亿,海量的用户每天产生海量的数据;美团外卖,每天都是几千万的订单,那这些系统的用户表订单表、交易流水等表是如何处理的呢?
数据只增不减,历史数据又必须留存,非常容易成为性能的瓶颈,而要解决这样的数据库瓶颈问题,"读写分离"和缓存往往都不合适,目前比较普通的方案就是NoSQL/NewSQL或者采用分表分库。
使用分表分库时,主要有垂直拆分和水平拆分两种拆分模式,都属于物理空间的拆分。
分表分库方案:只分库、只分表、分库又分表
垂直拆分:由于表述了多导致的单个库大。
水平拆分: 由于表记录多导致的单个表大。
拆分方式
垂直拆分
垂直拆分又称为纵向拆分,垂直拆分是将表按库进行分离,或者修改表结构按照访问的差异将某些列拆分出去。应用时有垂直分库和垂直分表两种方式,一般谈到的垂直拆分主要指的是垂直分库。
垂直拆分优点:
- 拆分后业务清晰,拆分规则明确。
- 易于数据的维护和扩展。
- 可以使得行数据变小,一个数据块(Block)就能存放更多的数据,在查询时减少IO次数。
- 可以达到最大化利用Cache的目的,具体在垂直拆分的时候可以将不常变的字段放一起,将经常改变的放一起。
- 便于实现冷热分离的数据表设计模式。
垂直拆分缺点:
- 主键出现冗余,需要管理冗余列。
- 会引起表链接join操作,可以通过在业务服务器上join来减少数据库压力,提高了系统的复杂度。
- 依然存在单表数据量过大的问题。
- 事务处理复杂。
水平拆分
水平拆分又称为横向拆分。相对于垂直拆分,它不再将数据按照业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个表仅包含数据的一部分。
水平分表是将一张含有很多记录数的表水平切分,不同的记录可以分开保存,拆分成几张结构相同的表。如果一张表中的记录数过多,那么会对数据库的读写性能产生较大的影响,虽然此时仍然能够正确地读写,单读写的速度已经到了业务无法忍受的地步,此时就需要使用水平分表来解决这个问题。
水平拆分:解决表中记录过多的问题。
垂直拆分:解决表中列过多或者表过多的问题。
水平拆分重点考虑拆分规则,例如:范围、时间或者hash算法等。
水平拆分优点:
- 拆分规则好确定,join操作基本可以数据库做。
- 不存在单表数据量过大的问题,高并发性能好。
- 切分的表结构相同,应用层改造少,只需要增加路由规则即可。
- 提高了系统稳定性和负载能力。
水平拆分缺点:
- 拆分规则难以抽象。
- 跨库join性能低。
- 分片事物的一致性难以解决。
- 数据扩容的难度和维护量变大。
日常工作中,我们通常会同事使用两种拆分方式,垂直拆分更偏向于产品、业务、功能拆分的过程,在技术上我们更关注于水平拆分。