数据库分库分表
为什么要分库分表
读写分离分散了数据库的读写压力,但是没有分散存储压力,数据库千万级别乃至上亿的时候,单库的存储能力会成为体统的瓶颈
1.数据量太大,读写性能降低,即使有索引,索引也会变得很大,性能下降;
2.数据文件很大,本分和恢复小号很长时间
业务分库
将业务表放在不同的数据库服务器上
会造成一些系统复杂度
1.join操作问题
无法使用sql的join语句,解决方法是join语句改为多条查询;
2.事务问题
使用mysql的xa性能太低,不满足高性能的要求,可以利用两阶段提交
3.成本问题
一台服务器变为多台,随着业务发展,用户数据体量达到千万,也有能力投入更多资金和人员进来,一开始没有必要分库分表,造成过度设计
垂直分表
适合表中某些不常用的占了大量空间的列拆出来,使查询时的性能得到提升,查全量数据就需要两次查询了
水平分表
有的公司要求数据量大于5000万必须分表,具体可以依据实际表的复杂度来看,当数据量达到千万级别,就应该警觉是否需要水平切分了
路由
水平分表后,某条数据具体是属于哪个子表,需要算法进行计算,会引入一定的复杂性;
常见的路由算法有
1范围路由:根据有序的数据列作为路由条件,列如id,时间戳。不同分段分散到不同的数据中
缺点是访问可能不均,新用户用可能比老用户更活跃
2.hash路由,根据hash算法,计算出数据该在哪个入库,确定是如果想扩展,hash要从新计算
3.配置路由,用一张独立的路由表来存储数据主键和表id,比如user_id和table_id
缺点是需要查询两次,另外如果数据量过大以后,路由表 有需要分库分表,又面临死循环的路由算法问题
引入复杂度
join
需要在代码中或者中间件中多次查询,合并结果
count
1.多个表分别计算count,之后相加,缺点是耗时
2.增加一个记录数表,table_name,row_count两个字段,缺点是无法条件过滤计算count
另外容易造成数据的不一致,也会造成数据库的写压力,innert和delete操作都要更新记录数表,对业务不敏感的数据可以通过后台定心刷新记录数
order by
用业务代码,或者中间件来操作