mysql 表分区
来源:互联网 发布:关于绘画的软件 编辑:程序博客网 时间:2024/06/11 03:45
通常来说,对于表的优化,除了对表结构的优化,还可以进一步使用分表或者表分区去提高效率。
主要介绍了表分区的几种分区方式和管理操作。(附带操作的SQL)
针对日常开发中我们经常会遇到大数据表,比如存储了百万级乃至千万级条记录的表。这样的表数据过于庞大,导致数据库在增删查改的时候耗时太长,效率低下,如果涉及到联合查询的情况,情况就更糟。所以,分表和表分区的目的也就是为了提高数据表的增删改查的效率。
先说下表分区的概念:
表分区是将一个表中的数据分段划分在多个位置存放,可以是同一块磁盘也可以是不同的磁盘或者不同的设备机器。表分区后,表面上还是一张表,但数据散列到多个位置了。读写的时候操作还是表名字,但是数据库会自动去组织分区的数据。
首先可以使用命令查看是否支持分区:
在5.6之前,查看当前配置是否支持分区:SHOW VARIABLES LIKE '%partition%';
在5.6以后,使用:SHOW PLUGINS;
显示ACTIVE就代表分区支持已激活。
讲表分区之前先说下myisam和Innodb两种存储引擎的数据结构。
myisam:
myisam的存储可以在mysql.ini或mysql.conf文件中查看数据保存。
打开这个目录可以看见有.myd 、.myi 、.frm 、.par文件。其中是.par是表分区的结构文件,如果没有分区则没有这个.par文件。
.myd 文件代表 数据信息文件 data文件
.myi 索引信息文件 index文件
.frm 表结构定义文件
db.opt 可以用记事本打开,只有
default-character-set=latin1
default-collation=latin1_swedish_ci
两个属性。
这两个属性是用来记录该库的默认字符集编码和字符集排序规则的。如果你当前创建数据库指定默认字符集和排序规则,那么后续创建的表如果没有指定字符集和排序规则,那么该新建的表将采用db.opt文件中指定的属性。
Innodb:
Innodb的数据信息文件存在此文件中,它是数据和索引整体一起存储的。但是表结构还是会存储到上面路径.frm文件中。
表分区支持的四种方式:
第一种:
HASH 取余分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。
以int字段hash分区
CREATE TABLE test_int_hash (
id INT (11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR (100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 PARTITION BY HASH (id) PARTITIONS 7;
以时间函数hash分区
CREATE TABLE test_month_hash (
id INT (11) NOT NULL AUTO_INCREMENT,
title VARCHAR (100) NOT NULL,
create_date datetime DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (id, create_date)
) ENGINE = INNODB DEFAULT CHARSET = utf8 PARTITION BY HASH (MONTH(create_date)) PARTITIONS 12;
第二种:
key分区:类似于按hash分区,区别在于key分区只支持计算一列或多列,且mysql服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
CREATE TABLE test_key(
id INT (11) NOT NULL AUTO_INCREMENT,
title VARCHAR (100) NOT NULL,
create_date datetime COMMENT '创建日期',
PRIMARY KEY (id)
) ENGINE = INNODB DEFAULT CHARSET = utf8 PARTITION BY KEY (id) PARTITIONS 4;
第三种:
range 分区:基于属于一个给定连续区间的列值,把多行分配给分区。如时间,连续的常量值等,按年分区。
CREATE TABLE test_range (
id INT (11) NOT NULL AUTO_INCREMENT,
title VARCHAR (100) NOT NULL,
birthday DATE,
PRIMARY KEY (id, birthday)
) ENGINE = myisam DEFAULT CHARSET = utf8 PARTITION BY RANGE (YEAR(birthday))(
PARTITION p_70 VALUES less than (1980),
PARTITION p_80 VALUES less than (1990),
PARTITION p_90 VALUES less than (2000),
PARTITION p_00 VALUES less than MAXVALUE
);
第四种:
list 分区:和range分区相似,区别在于list分区是基于列值匹配一个离散值集合中的某个值来进行选择。比如按照日期中的四个季节来分区。
CREATE TABLE test_list (
id INT (11) NOT NULL AUTO_INCREMENT,
title VARCHAR (100) NOT NULL,
birthday DATE,
PRIMARY KEY (id, birthday)
) ENGINE = myisam DEFAULT CHARSET = utf8 PARTITION BY list (month(birthday))(
PARTITION spring VALUES in(3,4,5),
PARTITION summer VALUES in(6,7,8),
PARTITION autumn VALUES in(9,10,11),
PARTITION winter VALUES in(12,1,2)
);
以上分区的截图,我用了Innodb和myisam两种引擎。
表分区管理:
1、key和hash都属于取余分区,所以操作是一样的。
alter table test_key add partition partitions N; --增加分区
alter table test_key_1 COALESCE partition N; --删减分区
--N代表再加或者再减几个分区
注意:采用取余算法的分区数量的修改,不会导致已有分区数据的丢失,因为执行会重新分配数据到新的分区。
2、range和list都属于条件分区,删除条件算法的分区,会导致分区数据丢失。添加分区则不会。
alter table test_range drop partition p_00;
alter table test_range add partition (partition p_00 VALUES less than (2010));
最后注意:
在实际业务中,我们会经常碰见平均分配,即按照主键进行key(primary key)。如果平均分配不适合,需要某种业务逻辑分区的话,就选择那种最容易被筛选的字段,如整型。
- MYSQL--表分区、查看分区
- mysql表分区
- MySql表分区
- MySQL的表分区
- MYSQL 表分区技术
- MySQL的表分区
- MySQL表分区
- MySql表分区
- mysql的表分区
- MySQL的表分区
- Mysql 表分区
- mysql 表分区
- MySQL的表分区
- Mysql的表分区
- mysql表分区
- mysql表分区
- MySQL的表分区
- mysql表分区
- lock condition 实例
- IMWEB训练营作业TODOLIST
- 什么是java序列化,如何实现java序列化?
- 动态代理实现原理
- MobaXterm 登录出现 Network error :Connection timed out
- mysql 表分区
- poj1873 The Fortified Forest【枚举+凸包】
- Log4j配置学习文档之一 log4j配置
- jsp接收后台全数字的字符串注意事项!
- 9.Unity3D商业游戏源码研究-变身吧主公-PanelBase
- NameError: global name 'log_runtime' is not defined in scapy
- SparkSQL之JDBC
- 预置GMS包后,关机闹钟失效
- Android的事件分发机制(一):dispatchTouchEvent