Mysql 分区和分表
2016-06-04 17:35
417 查看
为什么要分表和分区?
日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会更加糟糕。分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率。
方式:
1. Range(范围) 这种模式允许将数据划分不同范围。例如可以将一个表通过年份划分成若干个分区。
2. Hash(哈希) 这中模式允许通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。例如可以建立一个对表主键进行分区的表。
3. Key(键值) 上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。
4. List(预定义列表) 这种模式允许系统通过预定义的列表的值来对数据进行分割。
5. Composite(复合模式) 以上模式的组合使用
原理:
使用MRG_MyISAM 引擎(子表引擎为MyISAM)
创建主表的时候有个INSERT_METHOD,指明插入方式,取值可以是:0 不允许插入;FIRST 插入到UNION中的第一个表; LAST 插入到UNION中的最后一个表。
通过主表查询的时候,相当于将所有子表合在一起查询。这样并不能体现分表的优势,建议还是查询子表。
200万数据下的一次条件查询时间37秒:
进行分区:
分区完成:
重新查询:
时间为0.082秒
!其他分区方式定义
分表和分区不矛盾,可以相互配合的,对于那些大访问量,并且表数据比较多的表,我们可以采取分表和分区结合的方式(如果merge这种分表方式,不能和分区配合的话,可以用其他的分表试),访问量不大,但是表数据很多的表,我们可以采取分区的方式等。
分表技术是比较麻烦的,需要手动去创建子表,app服务端读写时候需要计算子表名。采用merge好一些,但也要创建子表和配置子表间的union关系。
表分区相对于分表,操作方便,不需要创建子表。
日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会更加糟糕。分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率。
分表
分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件。这些子表可以分布在同一块磁盘上,也可以在不同的机器上。app读写的时候根据事先定义好的规则得到对应的子表名,然后去操作它。方式:
1. Range(范围) 这种模式允许将数据划分不同范围。例如可以将一个表通过年份划分成若干个分区。
2. Hash(哈希) 这中模式允许通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。例如可以建立一个对表主键进行分区的表。
3. Key(键值) 上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。
4. List(预定义列表) 这种模式允许系统通过预定义的列表的值来对数据进行分割。
5. Composite(复合模式) 以上模式的组合使用
原理:
var getTableName = function() { var data = { name: 'tom', money: 2800.00, date: '201410013059' }; var tablename = 'account_'; var year = parseInt(data.date.substring(0, 4)); if (year < 2012) { tablename += 2011; // account_2011 } else if (year < 2013) { tablename += 2012; // account_2012 } else if (year < 2014) { tablename += 2013; // account_2013 } else if (year < 2015) { tablename += 2014; // account_2014 } else { tablename += 2015; // account_2015 } return tablename; }
使用MRG_MyISAM 引擎(子表引擎为MyISAM)
CREATE TABLE `master_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user` varchar(255) DEFAULT NULL, `pwd` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 INSERT_METHOD=LAST UNION=(`slave_table_1`,`slave_table_2`); CREATE TABLE `slave_table_1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user` varchar(255) DEFAULT NULL, `pwd` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; CREATE TABLE `slave_table_2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user` varchar(255) DEFAULT NULL, `pwd` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
创建主表的时候有个INSERT_METHOD,指明插入方式,取值可以是:0 不允许插入;FIRST 插入到UNION中的第一个表; LAST 插入到UNION中的最后一个表。
通过主表查询的时候,相当于将所有子表合在一起查询。这样并不能体现分表的优势,建议还是查询子表。
分区
分区和分表相似,都是按照规则分解表。不同在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器。分区后,表面上还是一张表,但数据散列到多个位置了。app读写的时候操作的还是大表名字,db自动去组织分区的数据。CREATE TABLE `train_user` ( `userid` int(11) DEFAULT NULL, `itemid` int(11) DEFAULT NULL, `behavior_type` int(11) DEFAULT NULL, `user_geohash` varchar(255) DEFAULT NULL, `catid` int(11) DEFAULT NULL, `time` datetime DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
200万数据下的一次条件查询时间37秒:
进行分区:
分区完成:
重新查询:
时间为0.082秒
!其他分区方式定义
分表和分区的联系
都能提高mysql的性高,在高并发状态下都有一个良好的表现。分表和分区不矛盾,可以相互配合的,对于那些大访问量,并且表数据比较多的表,我们可以采取分表和分区结合的方式(如果merge这种分表方式,不能和分区配合的话,可以用其他的分表试),访问量不大,但是表数据很多的表,我们可以采取分区的方式等。
分表技术是比较麻烦的,需要手动去创建子表,app服务端读写时候需要计算子表名。采用merge好一些,但也要创建子表和配置子表间的union关系。
表分区相对于分表,操作方便,不需要创建子表。
相关文章推荐
- mysql:The package 'mysql' can be found in following packages
- sparkstreaming实时统计并且存储到mysql数据库中
- mysql设置批量更新
- [MySQL] AUTO_INCREMENT lock Handing in InnoDB
- 安装zip格式mysql
- MySQL Delete,Update连表(left join)删除,更新语法
- 学习日志————MySQL练习
- 学习日志————关于MySQL中文乱码
- MySQL使用索引的场景及真正利用索引的SQL类型
- MySql默认约束
- Mysql 存储过程
- MySQL数据库事务中的行级锁,表级锁,页级锁
- Mysql 唯一约束
- 关系型数据库之Mysql二进制日志管理(四)
- MySQl自动编号与主键
- Mysql空值与非
- mysql-索引
- Mysql命令
- mysql转换类型
- 验证:mysql AUTO_INCREMENT 默认值是1