数据库分库分表

读写分离分散了数据库读写的压力,但没有分散存储的压力。

数据量达到千万甚至上亿的时候,单台数据库服务器的存储能力会成为系统的瓶颈,主要体现在:

    1. 数据量太大,读写的性能会下降,即使有索引,索引也会变的很大,性能同样会下降;

    2. 数据文件会变的很大,数据库备份和恢复会耗费很长的时间;

    3. 数据文件越大,极端情况下丢失数据文件的风险也越高。

业务分库:按照业务模块将数据分散到不同的数据库服务器。可分散存储和访问压力。

    存在问题:

        1. join问题:业务分库后导致原本在一个数据库中的表分散到不同的数据库中,导致无法使用sql的join;

        2. 事务问题:业务分库后导致原本在一个数据库中的表分散到不同的数据库中,无法通过事务统一修改;

        3. 成本代价:原来需要一台服务器解决的现在需要多台。

分表:垂直分表和水平分表。

    垂直分表:适合将表中某些不常用且占了大量空间的列拆分出去。其引入的复杂性主要体现在表的操作数量要增加,原来操作一张表现在需要操作多张表。

    水平分表:适合行数特别大的表,部分公司要求数据超过5000万之后分表

        复杂性体现在一下几个方面:

            1. 路由:水平分表后,某一条数据具体属于切分后的哪一张子表,需要增加路由算法进行计算,这个算法会引入一定的复杂性。

                  常见路由算法如下所示:

                (1)范围路由,选取有序的数据列作为路由的条件,不同分段分散到不同的数据库表中,比如按照id,按照范围1000000去分段,1-999999的分散到表1,1000000-1999999在表2..

                     复杂点:分段范围大小的选取上,太小会导致切分后字表数量过多,增加维护成本;太大则可能导致单表依然存在性能问题。一般建议在100万到2000万之间

                     优点:随着数据的增加平滑的扩充新的表。

                     缺点:分布不均匀,比如按照1000万来分表,可能某张表只有1000条,而某张表则有900万条。

                (2)hash路由:选取某个列的值进行hash运算,然后按照hash结果,分散到不同的数据库中去。

                     复杂点:初始表的数量选取上,表数量太多维护麻烦,表数量太少性能提升不明显。

                     优点:表分布比较均匀

                     缺点:扩充新表比较麻烦,所有数据都要重新分布。

                (3)配置路由,指路由表,用一张独立的路由表来记录信息。以用户id为例,新增一个路由表,放置两列,一个用户id列,一个table_id列进行关联。

                     优点:设计简单,使用灵活。扩充表时只需要迁移指定的数据,然后修改路由表即可。

                     缺点:必须多查询一次,影响性能;路由表本身太大也会成为性能瓶颈。

            2. join操作:水平分表后,数据分散在多个表中,如果需要与其他表进行join查询,需要在业务代码或者数据库中间件进行多次join查询。然后将结果合并。

            3.count() 操作:物理上将数据分散到多张表上,但业务逻辑上还是会将这些表当作一个表来进行处理。

                常见处理方法:

                (1)count() 相加,业务代码中对每个表进行count,然后加结果相加。实现相对简单,性能较低。

                (2)记录数表,新建一张表,包含表名和count字段。

            4. order by操作:水平分表后,数据分散在多个表中,排序无法在数据库中完成,需要在业务代码或者数据库中间件查询每个子表的数据。然后将结果合并排序。

posted @ 2022-11-24 16:42  夜雨声入眠  阅读(90)  评论(0编辑  收藏  举报