frm表结构文件,myd表数据文件,myi表索引文件。 INNODB engine对应的表物理存储文件 innodb的数据库的物理文件结构为: .frm文件 .ibd文件和.ibdata文件: 这两种文件都是存放innodb数据的文件,之所以用两种文件来存放innodb的数据,是因为innodb的数据存储方式能够通过配置来决定是使用共享表空间存放存储数据,还是用独享表空间存放存储数据。 独享表空间存储方式使用.ibd文件,并且每个表一个ibd文件 共享表空间存储方式使用.ibdata文件,所有表共同使用一个ibdata文件 创建分区 分区的一些优点包括: · 与单个磁盘或文件系统分区相比,可以存储更多的数据。 · 对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据。相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。 通常和分区有关的其他优点包括下面列出的这些。MySQL 分区中的这些功能目前还没有实现,但是在我们的优先级列表中,具有高的优先级;我们希望在5.1的生产版本中,能包括这些功能。 · 一些查询可以得到极大的优化,这主要是借助于满足一个给定WHERE 语句的数据可以只保存在一个或多个分区内,这样在查找时就不用查找其他剩余的分区。因为分区可以在创建了分区表后进行修改,所以在第一次配置分区方案时还不曾这么做时,可以重新组织数据,来提高那些常用查询的效率。 · 涉及到例如SUM() 和 COUNT()这样聚合函数的查询,可以很容易地进行并行处理。这种查询的一个简单例子如 “SELECT salesperson_id, COUNT(orders) as order_total FROM sales GROUP BY salesperson_id;”。通过“并行”, 这意味着该查询可以在每个分区上同时进行,最终结果只需通过总计所有分区得到的结果。 · 通过跨多个磁盘来分散数据查询,来获得更大的查询吞吐量。 简而言之就是 数据管理优化,查询更快,数据查询并行 检测mysql是否支持分区 复制代码 代码如下: mysql> show variables like "%partition%"; +-------------------+-------+ | Variable_name   | Value | +-------------------+-------+ | have_partitioning | YES  | +-------------------+-------+ 1 row in set
RANGE 分区:基于属于一个给定连续区间的列值,把多行分配给分区。 复制代码 代码如下: DROP TABLE IF EXISTS `p_range`; CREATE TABLE `p_range` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` char(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 /*!50100 PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (8) ENGINE = MyISAM) */;
range分区就是 partition by range(id) 表示按id 1-7的数据存储在p0分区;如果id大于7了则数据不能写入了,因为没有对应的数据分区来存储; 所以这时在创建分区时需要使用maxvalues关键字了 复制代码 代码如下: PARTITION BY RANGE (id) ( PARTITION p0 VALUES LESS THAN (8), PARTITION p1 VALUES LESS THAN MAXVALUE)
这样就表示,所有id大于7的数据记录存在在p1分区里。 RANGE分区在如下场合特别有用: · 当需要删除“旧的”数据时。如果你使用上面最近的那个例子给出的分区方案,你只需简单地使用 “ALTER TABLE employees DROP PARTITION p0;”来删除所有在1991年前就已经停止工作的雇员相对应的所有行。对于有大量行的表,这比运行一个如“DELETE FROM employees WHERE YEAR(separated) <= 1990;”这样的一个DELETE查询要有效得多。 · 想要使用一个包含有日期或时间值,或包含有从一些其他级数开始增长的值的列。 · 经常运行直接依赖于用于分割表的列的查询。例如,当执行一个如“SELECT COUNT(*) FROM employees WHERE YEAR(separated) = 2000 GROUP BY store_id;”这样的查询时,MySQL可以很迅速地确定只有分区p2需要扫描,这是因为余下的分区不可能包含有符合该WHERE子句的任何记录。 LIST 分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。 list分区可以理解为按一个键的id区间进行数据存储,比如类型表 1,2,3,4的所有记录存储在p0里面,5,6,7,8存在在p1分区里面 这里与range分区一样,如果现在有条记录typeid是9,那么这条记录是不能存入的; 需要注意的是:LIST分区没有类似如“VALUES LESS THAN MAXVALUE”这样的包含其他值在内的定义。将要匹配的任何值都必须在值列表中找到。 复制代码 代码如下: DROP TABLE IF EXISTS `p_list`; CREATE TABLE `p_list` ( `id` int(10) NOT NULL AUTO_INCREMENT, `typeid` mediumint(10) NOT NULL DEFAULT "0", `typename` char(20) DEFAULT NULL, PRIMARY KEY (`id`,`typeid`) ) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 /*!50100 PARTITION BY LIST (typeid) (PARTITION p0 VALUES IN (1,2,3,4) ENGINE = MyISAM, PARTITION p1 VALUES IN (5,6,7,8) ENGINE = MyISAM) */;
HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。 HASH分区主要用来确保数据在预先确定数目的分区中平均分布。在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合应该保存在哪个分区中;而在HASH分区中,MySQL 自动完成这些工作,你所要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。 要使用HASH分区来分割一个表,要在CREATE TABLE 语句上添加一个“PARTITION BY HASH (expr)”子句,其中“expr”是一个返回一个整数的表达式。它可以仅仅是字段类型为MySQL 整型的一列的名字。此外,你很可能需要在后面再添加一个“PARTITIONS num”子句,其中num 是一个非负的整数,它表示表将要被分割成分区的数量。如果没有包括一个PARTITIONS子句,那么分区的数量将默认为1。 复制代码 代码如下: DROP TABLE IF EXISTS `p_hash`; CREATE TABLE `p_hash` ( `id` int(10) NOT NULL AUTO_INCREMENT, `storeid` mediumint(10) NOT NULL DEFAULT "0", `storename` char(255) DEFAULT NULL, PRIMARY KEY (`id`,`storeid`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 /*!50100 PARTITION BY HASH (storeid) PARTITIONS 4 */;
可以看到代表p_sobpartitionp0.myd的文件消失了,取代的是p_subpartition#p#p0#sp#s1.myd 在MySQL 5.1中,对于已经通过RANGE或LIST分区了的表再进行子分区是可能的。 子分区是分区表中每个分区的再次分割,子分区既可以使用HASH希分区,也可以使用KEY分区。这 也被称为复合分区(composite partitioning)。 1,如果一个分区中创建了子分区,其他分区也要有子分区 2,如果创建了了分区,每个分区中的子分区数必有相同 3,同一分区内的子分区,名字不相同,不同分区内的子分区名子可以相同(5.1.50不适用) 分区注意点 1、重新分区时,如果原分区里面存在maxvalue则新的分区里面也必须包含maxvalue否则就错误。 alter table p_range2x reorganize partition p1,p2 into (partition p0 values less than (5), partition p1 values less than maxvalue); [Err] 1520 – Reorganize of range partitions cannot change total ranges except for last partition where it can extend the range 2、分区删除时,数据也同样会被删除 alter table p_range drop partition p0; 3、如果range分区列表里面没有maxvalue则如有新数据大于现在分区range数据值那么这个数据是无法写入到数据库表的。 4、修改表名不需要 删除分区后在进行更改,修改表名后分区存储myd myi对应也会自动更改。 如果希望从所有分区删除所有的数据,但是又保留表的定义和表的分区模式,使用TRUNCATE TABLE命令。(请参见13.2.9节,“TRUNCATE语法”)。 如果希望改变表的分区而又不丢失数据,使用“ALTER TABLE … REORGANIZE PARTITION”语句。参见下面的内容,或者在13.1.2节,“ALTER TABLE语法” 中参考关于REORGANIZE PARTITION的信息。 5、对表进行分区时,不论采用哪种分区方式如果表中存在主键那么主键必须在分区列中。表分区的局限性。 6、list方式分区没有类似于range那种 less than maxvalue的写法,也就是说list分区表的所有数据都必须在分区字段的值列表集合中。 7、在MySQL 5.1版中,同一个分区表的所有分区必须使用同一个存储引擎;例如,不能对一个分区使用MyISAM,而对另一个使用InnoDB。 8、分区的名字是不区分大小写的,myp1与MYp1是相同的。 分区的管理 range与list分区的改变动作不能适用于hash与key方式的分区。删除与添加动作是都能使用的。 以下面的例子 复制代码 代码如下: DROP TABLE IF EXISTS `p_list`; CREATE TABLE `p_list` ( `id` int(10) NOT NULL AUTO_INCREMENT, `typeid` mediumint(10) NOT NULL DEFAULT "0", `typename` char(20) DEFAULT NULL, PRIMARY KEY (`id`,`typeid`) ) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 /*!50100 PARTITION BY LIST (typeid) (PARTITION p0 VALUES IN (1,2,3,4) ENGINE = MyISAM, PARTITION p1 VALUES IN (5,6,7,8) ENGINE = MyISAM) */;