第一:首选垂直拆分
在进行数据库架构优化时,垂直拆分通常是首选的拆分策略,尤其是在数据库表数量多、业务复杂…等等情况下。
垂直拆分:是指根据不同的业务功能、或模块,将一个数据库中的多个表按功能划分到不同的数据库实例中。
每个数据库实例只处理特定功能模块的相关数据,从而实现业务模块之间的隔离,避免单一数据库实例承载过多的数据、和访问压力。
比如:淘宝电商平台的数据库,包含:多个模块,如用户、商品、订单、支付…等。
这些模块的数据表具有不同的业务特性,彼此之间的访问频率和数据量也存在差异,因此可以将它们拆分到不同的数据库中。
例如:
- 用户数据库:存储用户基本信息、登录数据、账户数据等。
- 交易数据库:存储订单信息、支付记录、交易日志等。
- 商品数据库:存储商品信息、库存数据、商品分类等。
- 店铺数据库:存储店铺信息、商家资料、商品发布等。
优点:
通过将数据按功能模块分割到不同的数据库中,可以有效减轻单一数据库实例的压力,提升系统的响应速度和处理能力。
并且,每个业务模块独立管理自己的数据,降低了模块之间的耦合度,使得数据库架构更容易维护和扩展。
缺点:
垂直拆分后的架构会涉及到多个数据库之间的协作,尤其是需要跨库的查询和事务处理,会引入复杂性和性能问题。
以及,在垂直拆分的系统中,如何保证跨数据库事务的一致性是一个挑战。
第二:其次水平拆分
当单一数据库实例的性能达到瓶颈时,“分库分表”,是扩展性能的一种有效手段。
分库
将数据库拆分为多个数据库实例,每个数据库实例存储部分数据。
目的是减少单一数据库的压力,提升性能与可扩展性。
分表
在同一个数据库实例内,将数据表拆分成多个小表。
每个小表存储原数据表的一部分数据,通常是按照某种规则(如ID范围、哈希值等)进行拆分。
假设一个电商系统中的订单表数据量非常大,我们可以按照用户ID进行水平分片:
- 创建多个数据库: db_order_0, db_order_1, db_order_2, …
- 计算分片键: 根据用户ID的哈希值,计算出该订单应该存储在哪个数据库中。
分库分表的核心在于如何将数据合理地分布到不同的库和表中。常见的分片策略有:
- 按范围分片(Range Sharding):根据某个字段的值范围将数据拆分到不同的分片中。比如按照时间范围、ID范围等。
- 按哈希分片(Hash Sharding):通过哈希算法将数据均匀分布到各个分片中,确保数据分布较为均匀。
- 按列表分片(List Sharding):根据某个字段的离散值将数据拆分到不同的分片中。例如,按照地区或产品类型进行分片。
- 复合分片:结合两种或多种分片策略,进行多维度的分片。
数据库拆分原则总结
- 优先考虑缓存:在进行数据库拆分之前,应优先考虑使用缓存(如Redis、Memcached)来减轻数据库的压力,尤其是读操作。
- 读写分离:对于读写压力较大的数据库,可以采用读写分离的方案,将读请求和写请求分发到不同的数据库实例上。
- 垂直拆分优先:在进行数据库拆分时,应优先考虑垂直拆分。垂直拆分可以根据业务功能或字段属性进行拆分,拆分后的表结构更加清晰,管理也更加方便。
- 水平拆分原则:
- 范围划分: 根据某个字段的范围进行划分,例如订单表可以按订单创建时间进行划分。
- 哈希划分: 根据字段的哈希值进行划分,可以保证数据均匀分布。
- 混合划分: 结合范围划分和哈希划分,以达到更好的效果。
- 数据一致性:在进行数据库拆分后,需要保证数据的一致性,可以使用分布式事务、最终一致性等方式来解决。
- 分库分表中间件:对于复杂的分布式数据库系统,可以使用分库分表中间件(如Sharding-JDBC、MyCat)来管理和维护。
mikechen睿哥
mikechen睿哥,十余年BAT架构经验,资深技术专家,就职于阿里、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》