merge:是SQL语句的一种。具体来说,MERGE语句会检查原数据表记录和目标表记录。如果记录在原数据表和目标表中均存在,则目标表中的记录将被原数据表中的记录所更新(执行Update操作);如果目标表中不存在的某(些)记录,在原数据表中存在,则原数据表的这(些)记录将被插入到目标表中(执行Insert操作)
一,先说一下为什么要分表
当一张表的数据达到几百万时,你查询一次所花的时间会很慢,此时用分表的方法可以减小单表查询的负担,缩短查询时间。
mysql执行sql的过程如下:
1,接收到sql;2,把sql放到排队队列中 ;3,执行sql;4,返回执行结果。在这个执行过程中最花时间在什么地方呢?第一,是排队等待的时间,第二,sql的执行时间。其实这二个是一回事,等待的同时,肯定有sql在执行。所以我们要缩短sql的执行时间。
为了保证数据的完整性mysql中有一种机制是表锁定和行锁定,myisam存储引擎是表锁定,innodb存储引擎是行锁定。表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行。行锁定也一样,别的sql必须等我对这条数据操作完了,才能对这条数据进行操作。如果数据太多,一次执行的时间太长,等待的时间就越长,这也是我们为什么要分表的原因。
二、使用merge存储引擎优缺点
优点:
1.查询数度比一张大表查询要快很多
1.引用多个数据表而无需发出多条查询,只用查询merge引擎这张表就可以查到所有。
2.适用于存储日志数据。例如,可以将不同月份的数据存入不同的表,然后使用myisampack工具压缩数据减少空间,最后通过MERGE表查询仍可以像往常那样工作。
3.可以更方便的维护,修复单个的小表要比修复大数据表更加容易。
4.多个子表映射至一个总表的速度极快。因为MERGE表本身不会存储和维护任何索引,索引都是由各个关联的子表存储和维护的,所以创建和重新映射MERGE表的速度非常快。
缺点:
1.总表(MERGE表)必须使用MRG_MyISAM存储引擎,子表必须使用MyISAM存储引擎,不可避免会受到MyISAM存储引擎的限制,MyISAM不支持事务操作。
2.MERGE表不能使用某些MyISAM特性。例如,子表可创建全文索引,MERGE表查询不能使用全文索引
3.一张表对应三个文件,1000个分表就是对应3000个文件,这样检索起来也会变的很慢
4.若使用ALTER TABLE语句修改MERGE表,那么会立即丢失总表和子表的映射关系,并且会将所有子表的数据拷贝至修改后的新表。
5.子表之间不能保证唯一键约束,只能保证单个子表内部的唯一性约束。
6.子表不支持分区(Partition)。
7.不支持INSERT DELAYED插入延时语句。
三、使用merge存储引擎来实现分表
1.子表必须使用MyISAM存储引擎,每个子表的表结构必须相同。
create table log_2001
(
id int not null auto_increment,
dt datetime not null,
info varchar(100) not null,
primary key(id),
index (dt)
) ENGINE = MyISAM;
create table log_2002 like log_2001;
2.建立merge表,merge表的表结构必须与各个子表结构相同,merge数据表也支持DELETE 、UPDATE、INSERT操作。MERGE数据表的定义里可以包括一个INSERT_METHOD选项,这个选项的可取值是NO、FIRST、LAST,他们的含义依次是禁止插入、插入到第一个字表、插入到最后一个字表。
create table log_merge
(
id int not null auto_increment,
dt datetime not null,
info varchar(100) not null,
primary key(id),
index (dt)
) ENGINE = MERGE UNION = (log_2001, log_2002)
INSERT_METHOD = FIRST;
3.创建一个新的子表,并让他有同样的表结构,然后修改log_merge数据表把新子表包括进来,注意UNION表必须同属一个DATABASE
create table log_2003 like log_2001;
alter table log_merge
UNION = (log_2001, log_2002,log_2003);
注意:
1.如果是通过修改.mrg文件的方式来修改MERGE表,那么一定要修改后要通过FLUSH TABLES刷新表缓存,否则修改不会生效。
2.查询结果及顺序与创建Merge表时联合表的顺序有关,例如:
INSERT INTO log_2001(id,dt,info)VALUES(1,'2017-01-01 11:00:00','测试01')
INSERT INTO log_2002(id,dt,info)VALUES(1,'2018-01-01 11:00:00','测试02')
SELECT * FROM log_merge WHERE id=1;
只会得到一条记录(1,'2017-01-01 11:00:00','测试01'),并不是两条记录,也不会是(1,'2018-01-01 11:00:00','测试02')。这是因为id是 primary key,如果在第一个表中查询到记录,则不在后面的表中记录查。如果id并没有定义唯一性约束,则这个查询会得到两条记录。
---------------------
作者:吾家陈小白
来源:CSDN
原文:https://blog.csdn.net/cw3225654/article/details/81335550
版权声明:本文为博主原创文章,转载请附上博文链接!