MySQL5.5的分区表

变更普通表baby_user_change_log为分区表

一、 表列描述

mysql> desc baby_user_change_log ;

+--------------+------------------+------+-----+---------+----------------+

| Field        | Type             | Null | Key | Default | Extra          |

+--------------+------------------+------+-----+---------+----------------+

| id           | int(11) unsigned | NO   | PRI | NULL    | auto_increment |

| account_id   | int(11) unsigned | NO   | MUL | NULL    |                |

| app_id       | int(11)          | YES  |     | NULL    |                |

| operate      | varchar(20)      | YES  |     | NULL    |                |

| old_data     | varchar(2000)    | YES  |     | NULL    |                |

| new_data     | varchar(2000)    | YES  |     | NULL    |                |

| change_data  | varchar(2000)    | YES  |     | NULL    |                |

| operate_time | int(11)          | YES  |     | NULL    |                |

+--------------+------------------+------+-----+---------+----------------+

二、 表结构特征

CREATE TABLE `baby_user_change_log` (

`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增id‘,

`account_id` int(11) unsigned NOT NULL COMMENT ‘account_id‘,

`app_id` int(11) DEFAULT NULL COMMENT ‘平台ID‘,

`operate` varchar(20) DEFAULT NULL COMMENT ‘操作类型‘,

`old_data` varchar(2000) DEFAULT NULL COMMENT ‘修改之前的数据‘,

`new_data` varchar(2000) DEFAULT NULL COMMENT ‘修改之后的数据‘,

`change_data` varchar(2000) DEFAULT NULL COMMENT ‘被修改的数据‘,

`operate_time` int(11) DEFAULT NULL COMMENT ‘时间‘,

PRIMARY KEY (`id`),

KEY `idx_account_id` (`account_id`)

)ENGINE=MyISAM AUTO_INCREMENT=18543058 DEFAULT CHARSET=utf8;

三、适合的分区方案

1)表总数据记录条数:

mysql> select count(*) from baby_user_change_log;

+----------+

| count(*) |

+----------+

| 18552945 |

+----------+

2)其中app_id 列具有按照RANGE分区的特征

mysql> select distinct(app_id) from baby_user_change_log;

+--------+

| app_id |

+--------+

|      7 |

|      5 |

|      3 |

|      1 |

+--------+

3)具体的分区表结构SQL

CREATE TABLE `baby_user_change_log_partition` (

`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘自增id‘,

`account_id` int(11) unsigned NOT NULL COMMENT ‘account_id‘,

`app_id` int(11) DEFAULT NULL COMMENT ‘平台ID‘,

`operate` varchar(20) DEFAULT NULL COMMENT ‘操作类型‘,

`old_data` varchar(2000) DEFAULT NULL COMMENT ‘修改之前的数据‘,

`new_data` varchar(2000) DEFAULT NULL COMMENT ‘修改之后的数据‘,

`change_data` varchar(2000) DEFAULT NULL COMMENT ‘被修改的数据‘,

`operate_time` int(11) DEFAULT NULL COMMENT ‘时间‘,

PRIMARY KEY (`id`,`app_id`),

KEY `idx_account_id` (`account_id`)

)ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8

PARTITION BY RANGE (app_id) (

PARTITION p0 VALUES LESS THAN (1),

PARTITION p1 VALUES LESS THAN (3),

PARTITION p2 VALUES LESS THAN (5),

PARTITION p3 VALUES LESS THAN (7),

PARTITION p4 VALUES LESS THAN MAXVALUE

);

4)插入数据

insert into baby_user_change_log_partition select* from baby_user_change_log;

5)验证结果

mysql> explain partitions select *  from baby_user_change_log_partition where app_id=1;

+----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+-------+-------+

| id | select_type | table                                   | partitions | type | possible_keys | key        | key_len | ref   | rows  | Extra |

+----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+-------+-------+

|  1 | SIMPLE      | baby_user_change_log_partition | p1         | ref  | idx_app_id    | idx_app_id | 4       | const | 25739 |       |

+----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+-------+-------+

1 row in set (0.00 sec)

mysql> explain partitions select *  from baby_user_change_log_partition where app_id=7;

+----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+------+-------+

| id | select_type | table                                   | partitions | type | possible_keys | key        | key_len | ref   | rows | Extra |

+----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+------+-------+

|  1 | SIMPLE      | baby_user_change_log_partition | p4         | ref  | idx_app_id    | idx_app_id | 4       | const |  276 |       |

+----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+------+-------+

1 row in set (0.00 sec)

mysql> explain partitions select *  from baby_user_change_log_partition;

+----+-------------+-----------------------------------------+----------------+------+---------------+------+---------+------+-------+-------+

| id | select_type | table                                   | partitions     | type | possible_keys | key  | key_len | ref  | rows  | Extra |

+----+-------------+-----------------------------------------+----------------+------+---------------+------+---------+------+-------+-------+

|  1 | SIMPLE      | baby_user_change_log_partition | p0,p1,p2,p3,p4 | ALL  | NULL          | NULL | NULL    | NULL | 56269 |       |

+----+-------------+-----------------------------------------+----------------+------+---------------+------+---------+------+-------+-------+

1 row in set (0.00 sec)

四、 分区表的原理及优缺点

1)分区表是什么?分区表是由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们也可以直接访问各个分区,

存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎),分区表的索引只是在各个

底层表上各自加上一个相同的索引,从存储引擎的角度来看,底层表和一个普通表没有任何不同,存储引擎也无须知道这是

一个普通表还是一个分区表的一部分。

2)在分区表上的操作按照下面的操作逻辑进行:

1.select查询:

当查询一个分区表的时候,分区层先打开并锁住所有的底层表,优化器判断是否可以过滤部分分区,

然后再调用对应的存储引擎接口访问各个分区的数据

2.insert操作:

当写入一条记录时,分区层打开并锁住所有的底层表,然后确定哪个分区接受这条记录,再将记录写入对应的底层表

3.delete操作:

当删除一条记录时,分区层先打开并锁住所有的底层表,然后确定数据对应的分区,最后对相应底层表进行删除操作

4.update操作:

当更新一条数据时,分区层先打开并锁住所有的底层表,mysql先确定需要更新的记录在哪个分区,然后取出数据并更新,

再判断更新后的数据应该放在哪个分区,然后对底层表进行写入操作,并对原数据所在的底层表进行删除操作

3)虽然每个操作都会打开并锁住所有的底层表,但这并不是说分区表在处理过程中是锁住全表的,如果存储引擎能够自己实现行级锁,

如:innodb,则会在分区层释放对应的表锁,这个加锁和解锁过程与普通Innodb上的查询类似。

4)分区表适用的场景

1.表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他都是历史数据

2.分区表的数据更容易维护,如:想批量删除大量数据可以使用清除整个分区的方式。另外,

还可以对一个独立分区进行优化、检查、修复等操作

3.分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备

4.可以使用分区表来避免某些特殊的瓶颈,如:innodb的单个索引的互斥访问,ext3文件系统的inode锁竞争等

5.如果需要,还可以备份和恢复独立的分区,这在非常大的数据集的场景下效果非常好

6.优化查询,在where字句中包含分区列时,可以只使用必要的分区来提高查询效率,

同时在涉及sum()和count()这类聚合函数的查询时,可以在每个分区上面并行处理,

最终只需要汇总所有分区得到的结果。

5)分区表的限制

1.一个表最多只能有1024个分区,包含子分区(mysql5.6之后支持8192个分区)

2.在mysql5.1中分区表达式必须是整数,或者是返回整数的表达式,

在5.5之后某些场景可以直接使用字符串列和日期类型列来进行分区

使用varchar字符串类型列时,一般还是字符串的日期作为分区。

3.如果分区字段中有主键或者唯一索引列,那么所有主键列和唯一索引列都必须包含进来,

如果表中有主键或唯一索引,那么分区键必须是主键或唯一索引

4.分区表中无法使用外键约束

5.mysql数据库支持的分区类型为水平分区,并不支持垂直分区,

因此mysql数据库的分区中索引是局部分区索引,一个分区中既存放了数据又存放了索引,

而全局分区是指的数据库放在各个分区中,但是所有的数据的索引放在另外一个对象中

6.目前mysql不支持空间类型和临时表类型进行分区。不支持全文索引

五、分区表的分区类型

1)分区表根据数据类型的特征适用不同的分区类型主要的类型有:

1.RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。

2.LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。

3.HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。

这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。

4.KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。

必须有一列或多列包含整数值。

分区表官方文档的解释与说明:

http://dev.mysql.com/doc/refman/5.5/en/partitioning.html

时间: 2024-12-30 02:47:18

MySQL5.5的分区表的相关文章

MySQL5.6.17分区表(二)

欢迎访问:鲁春利的工作笔记,学习是一种信仰,让时间考验坚持的力量. 子分区 http://dev.mysql.com/doc/refman/5.6/en/partitioning-subpartitions.html 又称为复合分区(composite partitioning),是在一个分区表中对分区的进一步拆分. CREATE TABLE ts_with_sub_partition (     id INT,      purchased DATE ) PARTITION BY RANGE(

MySQL5.6.17分区表

欢迎访问:鲁春利的工作笔记,学习是一种信仰,让时间考验坚持的力量. 环境说明: MySQL Version 5.6.17 参考MySQL官方文档: http://dev.mysql.com/doc/refman/5.6/en/partitioning.html 1.分区表概述 2.分区表类型 3.分区表管理

MySQL5.7传输表空间——迁移分区表

Mysql 传输表空间--将InnoDB分区表复制到另一个实例(二) 实验环境:(都是mysql5.7) 源库:192.168.2.200      mysql5.7.16    zhangdb下的emp_2分区表的 目标库:192.168.2.100    mysql5.7.18    test下  (将zhangdb的emp表,导入到目标库的test schema下) --:在源数据库中创建测试分区表emp_2,然后导入数据 MySQL [zhangdb]> CREATE TABLE emp

Mysql5.6—分区表及独享表空间

1.先停止Mysql [[email protected] ~]# /etc/init.d/mysqld stop Shutting down MySQL.[确定] 2.修改 /etc/my.cnf配置文件 [[email protected] ~]# vi /etc/my.cnf [mysqld]  innodb_file_per_table = 1 3.启动Mysql [[email protected] ~]# /etc/init.d/mysqld start Starting MySQL

MySQL 分区表原理及数据备份转移实战

1.分区表含义 分区表定义指根据可以设置为任意大小的规则,跨文件系统分配单个表的多个部分.实际上,表的不同部分在不同的位置被存储为单独的表.用户所选择的.实现数据分割的规则被称为分区函数,这在MySQL中它可以是模数,或者是简单的匹配一个连续的数值区间或数值列表,或者是一个内部HASH函数,或一个线性HASH函数. 分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表. 2.分区表优点 1)分区表更容易维护.对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有

MySQL分区表姿势

大部分内容整理自姜承尧的innodb存储引擎2学习笔记. 分区: 分区的功能不是在存储引擎层实现的.因此不只是InnoDB才支持分区.MyISAM.NDB都支持分区操作. 分区的过程是将一个表或者索引分解为多个更小.更可管理的部分.从逻辑上将,只有一个表或者索引,但是在物理上这个表或索引可能由数十个物理分区组成. 每个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理. MySQL只支持水平分区,不支持垂直分区. 水平分区:将同一表中不同行的记录分配到不同的物理文件中. 垂

Mysql5.7—mysql优化分区、分表(必备)

小生博客:http://xsboke.blog.51cto.com 小生 Q Q:1770058260 -------谢谢您的参考,如有疑问,欢迎交流 一. 分表 1. 分表简介 分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表. 如果正在使用的表需要进行分区,就需要同时修改app的规则,使mysql可以得知用户查询的数据在哪. 2. 分表类型 分为垂直切分和水平切分 垂直切分:将某些列分到另一个表 水平切分:将某些行分到另一个表 3. 分表的方式 1) Mysql集群 它并不是

MySQL 分区表

今天统计数据的时候发现一张表使用了表分区,借此机会记录一下. 1. 什么是表分区? 表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分.从逻辑上看,只有一张表,但是底层却是由多个物理分区组成. 2. 表分区与分表的区别 分表:指的是通过一定规则,将一张表分解成多张不同的表.比如将用户订单记录根据时间成多个表. 分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表. 3. 表分区有什么好处? 1)分区表的数据可以分布在不同的物理设备上,从而高效

MySQL的分区表

MySQL从5.1版本开始支持分区的功能.分区是指根据一定的规则,数据库把一个表分解成多个更小的.更容易管理的部分.就访问数据库的应用而言,逻辑上只有一个表或一个索引,但是实际上这个表可能由数十个物理分区对象组成,每个分区都是一个独立的对象,可以独自处理,可以作为表的一部分进行处理.分区对应用来说是完全透明的,不影响应用的业务逻辑. 1.查看使用的MySQL是否支持分区表. 5.6.1版本以后使用show plugins;命令查看 mysql> show plugins; +----------