分库分表方案

  • 水平分库:以字段为依据,按照一定策略(hash、range 等),将一个库中数据拆分到多个库中。
  • 水平分表:以字段为依据,按照一定策略(hash、range 等),将一个表中数据拆分到多个表中。
  • 垂直分库:以表为依据,按照业务归属不同,将不同表拆分到不同库中。
  • 垂直分表:以字段为依据,按照字段活跃性,将表中字段拆到不同表(主表和扩展表)中。

分表算法:
选定了分表字段之后,如何基于这个分表字段来准确的把数据分表到某一张表中呢?

这就是分表算法要做的事情了,但是不管什么算法,我们都需要确保一个前提,那就是同一个分表字段,经过这个算法处理后,得到的结果一定是一致的,不可变的。

通常情况下,当我们对order表进行分表的时候,比如我们要分成128张表的话,那么得到的128表应该是:order_0000、order_0001、order_0002.....order_0126、order_0127

通常的分表算法有以下几种:

直接取模:
在分库分表时,我们是事先可以知道要分成多少个库和多少张表的,所以,比较简单的就是取模的方式。

比如我们要分成128张表的话,就用一个整数来对128取模就行了,得到的结果如果是0002,那么就把数据放到order_0002这张表中。

比如表中有一万条数据,我们拆分为两张表,id 为奇数的:1,3,5,7……放在 user1 中, id 为偶数的:2,4,6,8……放在 user2 中,这样的拆分办法就是水平拆分了。

Hash取模:
那如果分表字段不是数字类型,而是字符串类型怎么办呢?有一个办法就是哈希取模,就是先对这个分表字段取Hash,然后在再取模。

但是需要注意的是,Java中的hash方法得到的结果有可能是负数,需要考虑这种负数的情况。

一致性Hash:
前面两种取模方式都比较不错,可以使我们的数据比较均匀的分布到多张分表中。但是还是存在一个缺点。

那就是如果需要扩容二次分表,表的总数量发生变化时,就需要重新计算hash值,就需要涉及到数据迁移了。

为了解决扩容的问题,我们可以采用一致性哈希的方式来做分表。
 

你可能感兴趣的:(mysql,数据库)