为什么要分库分表(设计高并发系统的时候,数据库层面应该如何设计)?

  • 首先要清楚,分库和分表是两回事,是两个独立的概念。分库和分表都是为了防止数据库服务因为同一时间的访问量(增删查改)过大导致宕机而设计的一种应对策略。

为什么要分库

按一般的经验来说,一个单库最多支持并发量到2000,且最好保持在1000。如果有20000并发量的需求,这时就需要扩容了,可以将一个库的数据拆分到多个库中,访问的时候根据一定条件访问单库,缓解单库的性能压力。

为什么要分表

分表也是一样的,如果单表的数据量太大,就会影响SQL语句的执行性能。分表就是按照一定的策略将单表的数据拆分到多个表中,查询的时候也按照一定的策略去查询对应的表,这样就将一次查询的数据范围缩小了。比如按照用户id来分表,将一个用户的数据就放在一个表中,crud先通过用户id找到那个表在进行操作就可以了。这样就把每个表的数据量控制在一定范围内,提升SQL语句的执行性能。

具体如何对数据库进行垂直拆分或水平拆分?

水平拆分的概念

水平拆分的意思,就是把一个表的数据拆分到多个库的多个表里面去。这里面的每个库的表结构都是一样的,只不过是表中存放的数据不一样,每个库表的数据汇总起来就是全部数据。水平拆分的意义在于将数据均匀地存放在各个库表里,依靠多个库来支持更高的并发,而且还能借助多个库的存储容量来进行扩容。

垂直拆分的概念

垂直拆分的意思,就是把一个有很多字段的表给拆分成多个表或者多个库上面去,每个库表的结构都不一样,每个库表都包含部分字段。一般来说,会将较少的访问频率很高的字段放到一个表里面去,然后将较多的访问频率很低的字段放到另外一个表里面去。因为数据库是有缓存的,你访问频率高的行字段越少,就可以在缓存里面缓存更多的行,性能也就越好。这个一般在表层面做的较多一些。

水平拆分(分库)和垂直拆分(分表)的场景

  • <mark>分库提高并发能录,分表提高SQL的执行能力</mark>

  • 所谓表层面的拆分,就是分表。具体就是将一个表拆分为N个表,让每个表的数据量控制在一定的范围内,保证SQL的性能。否则,单表的数据量越大,SQL的性能也就越差,一般是200万行左右,不要太多。如果你的SQL越复杂,就尽量让单表的行数越少。

  • 无论是分库还是分表,主流的数据库中间件都是可以支持的。这些中间件可以在你分库分表之后,根据指定的某个字段值自动路由到对应的库和对应的表上面。这时就只要考虑项目如何分库分表就行了。一般来说,垂直拆分,可以在表层面做,即对一些字段特别多的表做一下拆分;水平拆分的话,可能是因为并发承载不了或容量承载不了,也就可以按某个字段去分布到不同的库表里面去。

分库分表的两个方案

这里说一下两种分库分表的方案和它们的优缺点。

1.按照range范围来分比如说按照时间范围来分库分表,每个库表中存放的都是连续时间范围的数据。但是这种方式一般很少用,因为很容易会产生热点问题,大量的流量都打在最新的数据上了。这种方案的优点在于扩容的时候非常简单,比如只要预备好每个月都准备一个库就可以了,到了下一个新的月份自动将数据写入新的库。缺点则是,如果大部分请求都是访问最新的数据,那么在这里,分库分表的设计目的就只是简单的扩容,而不是为了应对高并发了。

2.按照hash分发。按照某个字段的hash值均匀分散,这个较为常用。优点在于可以平均分配每个库表的数据量和请求压力;缺点在于扩容比较麻烦,因为会存在一个数据迁移的过程,即之前的数据需要重新计算hash值并重新分配到不同的库表中。