随着用户数的不断增加,以及数据量的不断增加,通过分库与分表的方式提高查询性能的同时,带来了一系列分布式困境。

数据迁移与扩容问题

前面介绍到水平分表策略归纳总结为随机分表和连续分表两种情况。连续分表有可能存在数据热点的问题,有些表可能会被频繁地查询从而造成较大压力,热数据的表就成为了整个库的瓶颈,而有些表可能存的是历史数据,很少需要被查询到。连续分表的另外一个好处在于比较容易,不需要考虑迁移旧的数据,只需要添加分表就可以自动扩容。随机分表的数据相对比较均匀,不容易出现热点和并发访问的瓶颈。但是,分表扩展需要迁移旧的数据。
针对于水平分表的设计至关重要,需要评估中短期内业务的增长速度,对当前的数据量进行容量规划,综合成本因素,推算出大概需要多少分片。对于数据迁移的问题,一般做法是通过程序先读出数据,然后按照指定的分表策略再将数据写入到各个分表中。

表关联问题

在单库单表的情况下,联合查询是非常容易的。但是,随着分库与分表的演变,联合查询就遇到跨库关联和跨表关系问题。在设计之初就应该尽量避免联合查询,可以通过程序中进行拼装,或者通过反范式化设计进行规避。

分页与排序问题

一般情况下,列表分页时需要按照指定字段进行排序。在单库单表的情况下,分页和排序也是非常容易的。但是,随着分库与分表的演变,也会遇到跨库排序和跨表排序问题。为了最终结果的准确性,需要在不同的分表中将数据进行排序并返回,并将不同分表返回的结果集进行汇总和再次排序,最后再返回给用户。

分布式事务问题

随着分库与分表的演变,一定会遇到分布式事务问题,那么如何保证数据的一致性就成为一个必须面对的问题。目前,分布式事务并没有很好的解决方案,难以满足数据强一致性,一般情况下,使存储数据尽可能达到用户一致,保证系统经过一段较短的时间的自我恢复和修正,数据最终达到一致。

分布式全局唯一ID

在单库单表的情况下,直接使用数据库自增特性来生成主键ID,这样确实比较简单。在分库分表的环境中,数据分布在不同的分表上,不能再借助数据库自增长特性。需要使用全局唯一 ID,例如 UUID、GUID等。关于如何选择合适的全局唯一 ID,我会在后面的章节中进行介绍。

总结

分库与分表主要用于应对当前互联网常见的两个场景:海量数据和高并发。然而,分库与分表是一把双刃剑,虽然很好的应对海量数据和高并发对数据库的冲击和压力,但是却提高的系统的复杂度和维护成本。

因此,我的建议:需要结合实际需求,不宜过度设计,在项目一开始不采用分库与分表设计,而是随着业务的增长,在无法继续优化的情况下,再考虑分库与分表提高系统的性能。


更多相关文章

  1. 常用数据结构的 JavaScript 实现代码[每日前端夜话0xED]
  2. 选择合适的数据存储方案
  3. 服务端指南 数据存储篇 | MySQL(08) 分库与分表设计
  4. 服务端开发指南与最佳实战 | 数据存储技术 | MySQL(07) 范式与反模
  5. 服务端开发指南与最佳实战 | 数据存储技术 | MySQL(06) 数据库安全
  6. 服务端开发指南与最佳实战 | 数据存储技术 | MySQL(05) 索引的排序
  7. 服务端开发指南与最佳实战 | 数据存储技术 | MySQL(04) 索引使用的
  8. 服务端开发指南与最佳实战 | 数据存储技术 | MySQL(03) 如何设计索
  9. 服务端开发指南与最佳实战 | 数据存储技术 | MySQL(01)数据类型的

随机推荐

  1. java.util.Date与java.sql.Date
  2. java之生成可重复执行的sql脚本
  3. Mysql-5.7 x64安装
  4. sqlite3使用教程1 SQLite 命令
  5. Linux系统下安装MySql 5.7.17 全过程
  6. SQL Sever数据库卡事务
  7. 查询自定义VO对象的sql
  8. 如果没有明确使用ISNULL,则左连接失败
  9. qt sql多重条件查询简便方法
  10. SQLServer行转列的问题