MySQL 合并表、分区表

合并表

合并表示一种早期的、简单的分区实现,在未来可能被淘汰,不推荐使用

限制:

  • 合并表和子表的字段、索引要完全相同
  • 即使子表上有主键限制,合并表中仍然会出现重复值
  • 如果删除其中一个子表,表可能还存在,带只能通过合并表访问(视操作系统而定)
  • 合并表上无法使用replace语法,无法使用自增长字段

特性:

  • 一个MyISAM表可以是多个合并表的子表
  • 可以直接复制.frm、.MYI、.MYD文件实现在不同服务器间复制子表
  • 可以只包含需要的数据,例如某段时间的数据
create table mtable1(data int not null primary key) engine=myisam;

create table mtable2(data int not null primary key) engine=myisam;

insert into mtable1 values(1),(2),(3);

insert into mtable2 values(2),(3),(4);

create table mtable(data int not null primary key) engine=merge union=(mtable1,mtable2) insert_method=last;

insert_method=last,当向合并表插入数据时,将数据插入到合并表所合并的最后一个表里(这里就是mtable2)

insert_method=First,(mtable1)

使用场景

1) 经典的例子就是日志记录。日志是只追加的,所以可以每天用一个表。每天创建新的表并把它加入到合并表中。也可以把以前的表从合并表中移除掉,把它转化为压缩的MyISAM表,再把它们加回到合并表中。

2) 日志追加这并不是合并表的唯一用途。它们通常都被用于数据仓库程序,因为它的另一个长处就是管理大量的数据。在实际中不太可能管理一个TB级别的表,但是如果是由单个50GB的表组成的合并表,任务就会简单很多。

       当管理极其巨大的数据库时,考虑的绝不仅仅是常规操作。还要考虑崩溃与恢复。使用小表是很好的主意。检查和修复一系列的小表比起一个大表要快得多,尤其是大表和内存不匹配的时候。还可以并行地检查和修复多个小表。

       数据仓库中另外一个顾虑就是如何清理掉老的数据。对巨型表使用DELETE语句最佳状况下效率不高,而在最坏情况下则是一场灾难。但是更改合并表的定义是很简单的,可以使用DROP TABLE命令删除老的数据。这可以轻易地实现自动化。

3) 合并表并非只对日志和大量数据有效。它可以方便地按需创建繁忙的表。创建和删除合并表的代价是很低的。索引可以像对视图使用UNION ALL命令那样使用合并表。但它的开销更低,因为服务器不会把结果放到临时表中然后再传递给客户端。这使得它对于报告和仓库化数据非常有用。例如,要创建一个每晚都会运行的任务,它会把昨天的数据和8天前、15天前、以及之前的每一周的数据进行合并。使用合并表就可以创建无须修改的查询,并且自动地访问合适的数据。甚至还可以创建临时合并表,这是视图无法做到的。


分区表

参考https://www.cnblogs.com/shengdimaya/p/5384884.html

问题:

  • NULL值会使分区过滤失效,分区表达式的值可以是NULL,这会使记录保存到第一个分区,第一个分区是一个特殊分区。在MySQL5.5中可以通过直接使用列而不是基于列的函数进行分区:partition by range columns(colName)
  • 选择分区的成本可能很高,可以通过限制分区数量来缓解此问题(键分区和哈希分区没有此问题)

作用:让某些特定的查询操作减少响应时间

形式:水平分区、垂直分区


查看是否支持分区

show variables like '%partition%';

查看优化器是否执行了分区过滤

explain partitions select * from tableName where ...;

只能在使用分区函数的列本身进行比较时才能过滤分区

alter table sales_by_day partition by range(YEAR(day))(
    partition p_2010 values less than (2010),
    partition p_2011 values less than (2011),
    partition p_2012 values less than (2012),
    partition p_catchall values less than maxvalue
)

explain partitions select * from sales_by_day where YEAR(day) = '2010';//无效

explain partitions select * from sales_by_day where day between '2010-01-01' and '2010-12-31';//有效

查看分区

SELECT PARTITION_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'rangetable';

创建分区表、创建分区

//1、range分区
create table rangetable(
empno varchar(20) not null,
salary int
)
partition by range(salary)
(
partition p1 values less than(1000),
partition po values less than maxvalue
);

//或者在已有表创建分区

alter table rangetable partition by range(salary)
(
partition p1 values less than(1000),
partition po values less than maxvalue
);
//-----------------------------------------------------


//2、list分区
create table listtable(
empname varchar(20),
deptno int
)
partition by list(deptno)
(
partition p1 values in (10,20),
partition p2 values in (30,40,50)
);

//或者在已有表创建分区

alter table listtable partition by list(deptno)
(
partition p1 values in (10,20),
partition p2 values in (30,40,50)
);
//-----------------------------------------------------


//3、hash分区
create table hashtable(
id int,
name varchar(20),
birthdate date not null
)
partition by hash(year(birthdate))
partitions 4;
//通过模数算法计算分区编号
//如果输入为2018-10-10,计算过程为:
//mod(year('2018-10-10'), 4)
//=mod(2018,4)
//=2
//所以记录保存在分区编号为2的分区空间


//4、线性hash分区
create table linearhashtable(
id int,
name varchar(20),
birthdate date not null
)
partition by linear hash(year(birthdate))
partitions 4;
//与hash分区的不同在于计算方法不同,分区编号通过2的幂算法计算得到


//5、key分区
create table keytable(
id int,
name varchar(20),
birthdate date not null
)
partition by key(birthdate)
partitions 4;
//使用类似password的算法计算


//6、复合分区







删除分区

//删除 mytable 表的 p1 分区
alter table mytable drop partition p1;

添加分区

alter table rangetable add partition(partition p3 values less than(3000));

alter table listtable add partition(partition p3 values in (50,60));

拆分分区


合并分区


猜你喜欢

转载自blog.csdn.net/qq_17613195/article/details/84095937