快捷搜索:  汽车  科技

数据库分库分表主键策略:数据库优化四分表

数据库分库分表主键策略:数据库优化四分表一般在有严格的自增 id 需求上,按照 id 水平分表按区间范围分表比如:一个统计只提供按月查询的功能,那么把表按月拆分成12个,毎个查询只查询一个表就够了。如果是按照地域来分,即使把表拆的在小,查询还是要联合所有的表来查,还不如不拆;按时间分表这种方式有一定的局限性,当数据有较强的时效性,如微博发送记录、微信消息等等。这种数据很少有用户会查询几个月前的数据,

分表

分表:【水平分表(行)】【垂直分表(列)】

数据库分库分表主键策略:数据库优化四分表(1)


水平分表

一张表的数据太多的时候要分表,如果一个表的记录数太多了,比如上千万条数据,而且需要经常检索,那我们就有必要优化一下;

如果拆成 100个表,那么每个表中的数据 就成了 10万条记录;

当然不可以胡乱拆分的,需要数据在逻辑上划分,一个好的划分有利于程序的简单实现,也可以充分利用水平分表的优势;

比如:一个统计只提供按月查询的功能,那么把表按月拆分成12个,毎个查询只查询一个表就够了。如果是按照地域来分,即使把表拆的在小,查询还是要联合所有的表来查,还不如不拆;


分表策略

按时间分表

这种方式有一定的局限性,当数据有较强的时效性,如微博发送记录、微信消息等等。这种数据很少有用户会查询几个月前的数据,

按区间范围分表

一般在有严格的自增 id 需求上,按照 id 水平分表

table1 id 从 1 ~ 100w

table2 id 从 100w ~ 200w

table3 id 从 200w ~ 300w

Hash 分表

通过一个原始目标的 ID 或者名称 通过一定的 HASH 算法计算出数据存储表的表名,然后访问相应的表;

最简单的 hash 算法: T_user Id0 1


垂直分表

有一些记录数并不多,可能也就几万条,但是表字段却很长,表占用空间很大,检索表时需要执行大量 I/O,严重降低了性能,这个时候需要把大的字段拆分到另一个表,并且该表与原表是一对一的关系(外键)

如果一张表某个字段,信息量大,但是我们很少查询,则可以考虑把这些字段,单独的放入到一张表中。如果硬是要查询,就是用跨表查询(join)

数据库分库分表主键策略:数据库优化四分表(2)

数据库分库分表主键策略:数据库优化四分表(3)


数据库分库分表主键策略:数据库优化四分表(4)

分区

不同在于分表将大表分解成为很多个独立的实体表,而分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器。

分区后,表面上还是有一张表,但是数据散列到多个位置了,消费者读写的时候操作的还是大表名字,db 自动去组织分区的数据;


分区优势
  1. 与单个磁盘或文件系统分区相比,可以存储更多的数据
  2. 很容就能删除不用或者过时的数据
  3. 一些查询可以得到极大的优化,可以并发查询
  4. 涉及到 SUM() / COUNT() 等聚合函数时,可以并发进行
  5. IO 吞吐量更大

分区方式

Range(范围)

基于一个给定的连续空间,把数据分配到不同分区

CREATE TABLE employees ( id INT NOT NULL name VARCHAR(30) hired DATE NOT NULL DEFAULT '20201-12-27' job VARCHAR(30) NOT NULL dept_id INT NOT NULL ) engine myisam partition BY RANGE (dept_id) ( partition p0 VALUES LESS THAN (6) partition p1 VALUES LESS THAN (11) PARTITION p2 VALUES LESS THAN (16) partition p3 VALUES LESS THAN (21) );


List(预定义列表)

类似Range分区,区别在 List 分区是基于枚举出的值列表分区,而Range分区是根据给定的连续区间范围区分

LIST分区通过使用“PARTITION BY LIST(expr)”来实现,其中“expr” 是某列值或一个基于某个列值、并返回一个整数值的表达式,然后通过“VALUES IN (value_list)”的方式来定义每个分区,其中“value_list”是一个通过逗号分隔的整数列表。

CREATE TABLE employees ( id INT NOT NULL name VARCHAR(30) hired DATE NOT NULL DEFAULT '20201-12-27' job_code INT store_id INT ) PARTITION BY LIST(store_id)( PARTITION pQY VALUES IN (3 5 6 17) PARTITION pJN VALUES IN (1 10 11 19) PARTITION pCH VALUES IN (4 12 14 18) PARTITION pJJ VALUES IN (2 9 13 16) PARTITION pGX VALUES IN ( 7 8 15 20) );


Hash(哈希)

通过对表的一个或多个列的 Hash Key 进行计算,最后通过这个 Hash 码不同数值对应的数据区域进行分区。

主要用来分散热点读,确保数据在预先确定个数的分区中尽可能平均分布。

CREATE TABLE employees ( id INT NOT NULL name VARCHAR(30) hired DATE NOT NULL DEFAULT '20201-12-27' job_code INT store_id INT ) PARTITION BY HASH(store_id) PARTITIONS 4

线性哈希与常规哈希区别

常规:哈希使用的是求哈希函数值的模式,缺点在于分区增加时的重新计算

线性:线性哈希功能使用的是一个线性的 2 的幂(powers-of-two)运算法则

线性哈希分区的优点在于增加、删除、合并和拆分分区将变得更加快捷,有利于处理含有极其大量数据的表。它的缺点在于,与使用

常规HASH分区得到的数据分布相比,各个分区间数据的分布不大可能均衡。


Key(键值)

是对 Hash 模式的一种延伸,这里的 Hash Key 是 MySQL 系统产生的,Composite(复合模式)

CREATE TABLE employees ( id INT NOT NULL name VARCHAR(30) hired DATE NOT NULL DEFAULT '20201-12-27' job VARCHAR(30) NOT NULL dept_id INT NOT NULL ) partition BY KEY (job) PARTITIONS 3;

与key不同在于key的值可以为空,但是要注意:

1) 可以不指定值,默认以主键为准

2) 如果没主键,以唯一键为准

3) 如果没主键,以唯一键为准,唯一键必须非空

4) 无主无唯一,就必须手动指定


数据库分库分表主键策略:数据库优化四分表(5)

留个关注!么么哒~~

猜您喜欢: