当前位置:Gxlcms > 数据库问题 > MySQL3-分区与分表

MySQL3-分区与分表

时间:2021-07-01 10:21:17 帮助过:9人阅读

。注意,oracle是在分区与索引时,是可以选择全局索引还是分区索引的。   1、RANGE 分区:基于属于一个给定连续区间的列值,把多行分配给分区。 (1)示例1: create table emp(     empno varchar(20) not null,     empname varchar(20),     deptno int,     birthdate date,     salary int ) partition by range(salary)(     partition p1 values less than (1000),     partition p2 values less than (2000),     partition p3 values less than maxvalue ); (2)示例2:(在本例中,没有直接使用列而是使用了表达式year(birthdate);使用表达式必须有返回值) create table emp(     empno varchar(20) not null ,     empname varchar(20),     deptno int,     birthdate date not null,     salary int ) partition by range(year(birthdate))(     partition p1 values less than (1980),     partition p2 values less than (1990),     partition p3 values less than maxvalue ); (3)maxvalue只能出现在最后一个分区;如果没有使用形如maxvalue,可能导致插入的数据不属于任何分区,从而导致数据无法插入(如:Table has no partition for value ……)   2、LIST 分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择;如果插入的数据不能匹配任何分区,则插入失败。 create table emp(     empno varchar(20) not null ,     empname varchar(20),     deptno int,     birthdate date not null,     salary int ) partition by list(deptno)(     partition p1 values in (10),     partition p2 values in (20),     partition p3 values in (30) );   3、HASH分区:基于用户定义的表达式的返回值进行选择,该表达式使用一个或多个列值进行计算;这个表达式可以是任何产生非负整数值的表达式。 (1)目标:确保数据在预先确定数目的分区中平均分布。不需要指定一行数据在哪个分区中(RANGE和LIST需要),MySQL自动完成;只需要指定表达式以及分区数量。hash分区和key分区,经过测试,有个奇怪的特点:当分区数量为奇数时,分布较为平均;当分区质量为偶数时,则会出现一半分区没有元素的现象。【网上说是质数和合数,但我测试发现,2不平均,而9/15等则较为平均,故猜测是奇数和偶数】 (2)示例 create table emp(     empno varchar(20) not null ,     empname varchar(20),     deptno int,     birthdate date not null,     salary int ) partition by hash(year(birthdate))     partitions 4;//4表示分成4份     4、KEY分区:类似于按HASH分区,区别在于KEY分区不能指定表达式,只能指定一列或多列;同样需要指定分区数量。 create table emp(     empno varchar(20) not null ,     empname varchar(20),     deptno int,     birthdate date not null,     salary int ) partition by key(birthdate)     partitions 4;   5、复合分区:包括range-hash、range-key、list-hash、list-key 示例:range-hash create table emp( empno varchar(20) not null , empname varchar(20), deptno int, birthdate date not null, salary int ) partition by range(salary) subpartition by hash(year(birthdate)) subpartitions 3( partition p1 values less than (2000), partition p2 values less than maxvalue );       三、分区表的管理 1、删除分区:同时删除分区内的数据;只可以用于range和list。 alter table emp drop partition p1; alter table emp drop partition p2,p3;   2、增加分区:如果range分区中使用了maxvalue,则无法在后面增加分区,因为形如maxvalue必须是最后一个分区;可以先删除再添加,但是如果有数据在最后一个分区,会导致数据丢失。只可以用于range和list;不会丢失数据。 alter table emp add partition (partition p3 values less than (4000)); alter table emp add partition (partition p3 values in (40));   3、分解分区:只可以用于range和list;不会丢失数据。 alter table emp reorganize partition p1 into( partition p1 values less than (100), partition p3 values less than (1000) );   4、合并分区:只可以用于range和list;不会丢失数据。 alter table emp reorganize partition p1,p3 into (partition p1 values less than (1000));   5、重新定义分区表:可以用于四种分区表;不会丢失数据。 alter table emp partition by hash(salary)partitions 7;---hash alter table emp partition by range(salary)( partition p1 values less than (2000), partition p2 values less than (4000) );---range   6、删除所有分区:可以用于四种分区表;不会丢失数据。 alter table emp remove partitioning;   7、重建分区:可以用于四种分区表;不会丢失数据。当用于hash和key分区时,可以先查询分区名称再重建(因为不是我们指定的),不过一般是p0,p1,p2...的形式。用于整理分区碎片,效果与先删除保存在分区中的记录,再将它们插入相同。 ALTER TABLE emp rebuild partition p1,p2;   8、优化分区:可以用于四种分区表;不会丢失数据。如果从分区中删除了大量的行,或者对一个带有可变长度的行作了许多修改,可以用来收回没有使用的空间,并整理分区数据文件的碎片。【我的MySQL不支持:Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.】 ALTER TABLE emp optimize partition p1,p2;   9、保存分区:可以用于四种分区表;不会丢失数据。读取并保存分区的键分布;保存到哪里呢??? ALTER TABLE emp3 analyze partition p1,p2;   10、检查分区:可以用于四种分区表;不会丢失数据。判断数据或索引是否已经被破坏,如果破坏使用修复分区进行修复。 ALTER TABLE emp CHECK partition p1,p2;   11、修复分区:可以用于四种分区表;不会丢失数据。 ALTER TABLE emp repair partition p1,p2;       四、获取分区表信息 1、show create table 表名 2、show table status:可以查看是不是分区表;不加表明,显示数据库内所有表的状态 3、查看information_schema.partitions表  select partition_name part, partition_expression expr, partition_description descr, table_rows from information_schema.partitions where table_schema = schema() and table_name=‘表名‘; 应该注意到,查询到分区表的数据统计未必准确(有时连续查询没有变动的表结果都可能不同);准确与否与搜索引擎有关,比如Innodb的不准确。 4、explain partitions select语句:通过此语句来显示扫描哪些分区,及他们是如何使用的;因此可以查看分区是否对查询过程有优化效果。       五、分区的局限与分表 1、分区与索引 (1)作用类似 在执行查询时,优化器会根据分区定义过滤那些没有我们需要数据的分区,否则分区对查询的优化就没有什么效果了。因此,查询条件应该与分区列匹配。 理解分区:可以将分区当做索引的最初形态,以代价非常小的方式定位到需要的数据在哪一片“区域”。这样也就可以理解,无论是分区还是索引,都要求查询条件与之匹配,查询才有优化效果。 (2)有索引为什么还需要分区 当表数据量超大的时候,索引是有问题的。一方面,除非索引覆盖了查询,否则数据库根据索引扫描的结果去数据库中查找,如果数据量巨大,将产生大量随机I/O,数据库响应时间会超长。另一方面,索引也会很大。 (3)实现细节 分区表的底层由多个物理子表实现,因此分区表的索引只是在各个底层表上各自加上一个完全相同的索引;没有全局索引一说。 (4)问题:分区列和索引列不匹配 如果分区列和索引列不匹配,那么根据索引的条件查询,不能够过滤分区;就会导致需要把每个分区的索引都读到内存,效率极低,尽量避免。 但是实际上,有些时候很难避免索引列与分区列不一致:比如某些表有不止一个索引。 此时,可以考虑分表。   2、分表 (1)顾名思义,当数据量过大时,将不同的数据放到不同的表中。选取用于分表的字段和规则应该注意,这个字段应比较常用(因为每次增删改查都需要根据这个字段确定使用哪个表),也尽量不要使用完全随机数(不好根据规则确定表)。 (2)动态sql:在应用层进行判断,选择增删改查所使用的表;代码略繁琐,且随着新加表,需要发版。使用Hibernate的sql功能,直接用sql语句和表名进行操作;PO不与表绑定(严格来说不是PO)。 (3)NamingStrategy:传入一个表名,命名策略可以输出一个表名;但是由于输入只有表名,因此不可能根据数据的不同动态选择表名。命名策略一般做的事情是进行一些大小写转换,加前后缀,或者在表名中加入当前时间的信息(这个在每天的表都需要单独存,且以后不需要访问今天的表或访问时会带上时间时比较有用)。 (4)hibernate shards:google提交给hibernate社区的源码。每个分片都要有自己的配置文件,强项是分库。 (5)Inceptor:在hibernate生成最终的sql语句之前,对sql进行一些改变。这个功能挺强大,而且将对分表的处理放在了最底层,逻辑上比较通顺。但是也有一些弊端:代码繁琐;每个sql都会被拦截,可能会出问题;对写sql的格式会有一定要求(这样拦截时才容易判断出哪些是真正需要拦截的);不直观。    

MySQL3-分区与分表

标签:通过   http   net   区间   分解   指定   orm   表示   奇数   

人气教程排行