sql left join之后数据量增加了_当写入数据增加时,如何分库分表

数据库优化--当写入数据增加时,如何实现分库分表?

高并发下数据库的一种优化方案:读写分离。就是一老主从复制的技术使得数据库实现数据复制多份,增加抵抗大量并发的得写能力。提升数据库的查询性能。以提高数据的安全性,

50653eecb3c2ddfef083f26c5a6fcd43.png

数据库订单量突破5000w ,订单单表存储,读写性能都将下降,数据库磁盘也会爆浆,因此需要心情更高效的解决方式,方便西戎继续正常运转。

随着数据量的增加,这时要考虑如下问题:

  • 系统数据不断增加,单表超过千万甚至上亿级别,这时就算使用了索引,索引的占用空间也将随着数据量的增大而增大,这样会影响到查询性能。如何提升查询性能?
  • 数据量的增加也占据的磁盘空间,数据库备份和恢复时间变长,如何让数据库系统支持如此大的数据量?
  • 不同模块的数据,如果全部存在一个库,一旦发生故障,所有模块都将受到影响,如何做到不同模块是故障隔离的?
  • 4核8G 的服务器,大体可以支持500 TPS 和10000QPS ,数据库的写能力弱于数据查询能力,随着数据量的增加,如何提高系统的并发写入请求?

答案是: 分库分表

数据的写入请求造成大量性能、可用性等问题,要解决这些问题,要做的就是分片,突破单机数据库的瓶颈。

如何对数据库做垂直拆分

不同于主从复制的数据是全量拷贝到多个节点,分库分表后,每个节点保存部分的数据,这样可以有效的减少单个数据库节点和单个数据表中存储的数据量。在解决了数据存储瓶颈的同时,有效的提升数据查询的性能。

数据库分表的方式有两种:垂直拆分和水平拆分。

垂直拆分

垂直拆分原则一般是按照业务进行拆分,核心思想是专库专用,量业务耦合度比较高的表拆分到单独的库中,把不同的业务数据拆分到不同的数据库节点,这样一旦数据库发生故障只会影响到某一个模块的功能,不会影响到整体功能。从而实现数据层面的故障隔离。

如果单一数据库或者数据表无法满足存储和查询需求,这个时候对数据库和数据表做水平拆分。

数据库如何水平拆分

拆分的规则,一般如下:

  • hash 分表 按照某个字段做 hash 值拆分,这种拆分方式适用于实体表,比如用户表,内容表,这些实体表可以以实体表的 ID 字段来拆分。

72478c3fa549cc0f0ce24acd8862b7dd.png
  • 按照时间字段区间来拆分

按照时间字段拆分,比如常用的时间字段,内容表中都有创建时间, 我们可能需要使用时间字段来查看一个人发布的内容,比如你想看昨天发布的朋友圈,或者一个月前的朋友圈,这样就朋友圈内容表,就可以采用“创建时间”这个时间字段来做分库分表。

一般来说,一个人一段时间的订单,一段时间发布的朋友圈内容,这些都可以采用时间字段来分库分表。采用这个拆分规则,一般需要提前建表。

250190b57d42ee3db325c9fb76cfaa65.png

分库分表之后,数据的访问带来了很大的改变,原先的查询条件从数据库中查就可以,但是使用分库分表之后,需要确定数据在哪个表,然后再到哪个库表中查询数据,这种复杂度会可以使用中间件来处理。比如 TDDL Sharding-JDBC 来实现。

分库分表带来的问题

问题:分片键

分库分表引入的一个问题就是分库分表键,也叫做分区键,分库分表规则无论是 hash 分表还是 时间字段拆分,每次都要选取这个数据库字段,才能找到数据所在的库和表,否则只能向所有库的所有表发送查询命令。如果一个表被分成 16个库和64 个表,那么一次查询会变成 16*64=1024 次查询。

有什么方法解决?

建立映射表,比如用户表是采用ID 作为分片键的,可以通过用户昵称和 ID 做一张映射表,当要查询的时候,先通过昵称找到ID ,然后找到对应的表,这样就能找到对应哪个库,哪个表的数据。

问题: 数据库特性的实现困难

如果多表 JoIn 在单表是通过一个SQL 完成的,但是分库分表之后,无法跨库执行 SQL,不过一般来说对 JOIN 操作需求不高,如果有可以把两个表数据取出来,然后在业务层做处理。 其次比如 Count() 操作,数据被分散到多个表,这样只能一个表 count, 当然,也可以采用 在分布式缓存 Redis 中记录数据总数。

总结

分库分表,必然会带来不便,但是能够提升数据库的扩展性和提升读写性能,避免单机的容量和请求量的限制。解决数据量过大导致的性能和容量瓶颈。

分库分表主要方式垂直拆分和水平拆分,水平拆分方式有 Hash 分表,或者按照时间字段拆分,分库分表带来的分片键可使用映射表来处理。

  1. 如果没有性能瓶颈,尽量不分库分表
  2. 如果要做,就一次性做到位。
  3. NoSQL 数据库 Hbase 、MongoDB 有自动分片特性,可以考虑代替传统关系型数据库。

欢迎关注公众号:程序员开发者社区

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值