Mysql经过Merge引擎进行分表
转载: https://www.jianshu.com/p/9420a6a8ae2ejavascript
https://www.cnblogs.com/xbq8080/p/6628034.htmlphp
使用场景
- 数据表记录很大,单表记录会超过1000W,好比用户表等。
测试环境
- Mysql5.7
注意
分表的id不能是自增(auto increment)的; 分表必须使用MyISAM存储引擎; 每一个分表的表结构必须相同; MySQL必须具备存储分表数据文件和索引文件的目录的读写权限; 必须启用MySQL的符号连接支持功能。 总表的表结构必须与各个分表相同; 总表必须使用MRG_MyISAM存储引擎; 总表不会建立任何数据文件和索引文件; MRG文件存储总表须要映射的子表的表名; 总表自己不存储任何数据和索引; INSERT_METHOD须要设置为NO,或者不配置; 总表的id不能是自增(auto increment)的。
MERGE分表的优势
- MERGE分表能够解决下面的问题:
适用于存储日志数据。例如,能够将不一样月份的数据存入不一样的表,而后使用myisampack工具压缩数据,最后经过一张MERGE表来查询这些数据。 能够得到更快的速度。能够根据某种指标,将一张只读的大表分割成若干张小表,而后将这些小表分别放在不一样的磁盘上存储。当须要读取数据时,MERGE表能够将这些小表的数据组织起来,就好像使用先前的大表同样,可是速度会快不少。 能够提升搜索效率。能够根据某种指标将一张只读的大数据表分割为若干个小表,而后根据不一样的查询维度,能够获得若干种小表的组合,而后再为这些组合分别建立不一样的MERGE表。例如,有一张只读的大数据表T,分割为T一、T二、T三、T4,共4张小表,有两种查询维度A和B,A能够获得小表组合T一、T2和T3,B能够获得小表组合T二、T3和T4,分别为A和B建立两个MERGE表,也就是M1和M2,这两个MERGE表分别关联的小表是存在交叠的。 能够更加有效的修复表。修复单个的小表要比修复大数据表更加容易。 多个子表映射至一个总表的速度极快。由于MERGE表自己不会存储和维护任何索引,索引都是由各个关联的子表存储和维护的,因此建立和从新映射MERGE表的速度很是快。 不受操做系统的文件大小限制。单个表会受到文件大小的限制,可是拆分红多个表,则能够无限扩容。 MERGE表还能够用来给单个表建立别名,而且几乎不会影响性能。
MERGE分表的问题
总表(MERGE表)必须使用MRG_MyISAM存储引擎,子表必须使用MyISAM存储引擎,不可避免会受到MyISAM存储引擎的限制。
MERGE表不能使用某些MyISAM特性。例如,虽然能够为子表建立全文索引,可是却不能使用全文索引,经过MERGE表查询数据。
MERGE表会使用更多的文件描述符。若是有10个客户端使用1张MERGE表,那么就须要消耗(10×10)+10个文件描述符(其中,10个客户端分别有10个数据文件描述符,而且会共享使用10个索引文件描述符)。 若使用ALTER TABLE语句修改总表的存储引擎,那么会当即丢失总表和子表的映射关系,而且会将全部子表的数据拷贝至修改后的新表。 总表和子表的主键都不能使用自动增加(auto increment)。 子表之间不能保证惟一键约束,只能保证单个子表内部的惟一性约束。 因为不能保证惟一键约束,致使REPLACE语句的行为会不可预期,INSERT ... ON DUPLICATE KEY UPDATE语句也有相似问题。所以,只能使用路由策略,对子表使用这些语句,而不能对总表使用。 子表不支持分区(Partition)。 当正在使用总表时,不能对任何子表执行ANALYZE TABLE、REPAIR TABLE、OPTIMIZE TABLE、ALTER TABLE、DROP TABLE、DELETE或TRUNCATE TABLE语句,不然会致使不可预期的结果。 总表和子表的表结构必须彻底一致。 总表能够映射的全部子表的总行数上限为 264 行。 不支持INSERT DELAYED语句。
创建数据库
CREATE database `test` DEFAULT CHARACTER SET utf8 ;
创建子表
- 分表必须使用MyISAM存储引擎,而MyISAM表的数据文件(.MYD文件)和索引文件(.MYI文件)是能够分散在不一样的磁盘或目录上存储的。
- 建立数据表的时候能够制定存储目录,如:指定 DATA DIRECTORY = '/home/user3' INDEX DIRECTORY = '/home/user3';
- 在Shell中执行如下命令,建立存储子表数据和索引的目录:
# 建立存储user1表数据和索引的目录 mkdir -p /home/user1 chown -R mysql:mysql /home/user1 # 建立存储user2表数据和索引的目录 mkdir -p /home/user2 chown -R mysql:mysql /home/user2 # 建立存储user3表数据和索引的目录 mkdir -p /home/user3 chown -R mysql:mysql /home/user3
- 启用MySQL的have_symlink选项,使得MySQL支持符号连接,不然就不能指定MyISAM表的数据文件和索引文件的存储路径。在Shell中执行如下命令,编辑my.cnf文件:
vi /usr/local/MySQL/etc/my.cnf
- 在my.cnf文件的[mysqld]分段中添加:
symbolic-links
- 保存my.cnf文件以后,从新启动mysql服务:
service mysqld restart
- 建立user一、user二、user3分表,执行如下SQL:
CREATE TABLE `user1` ( `id` INT NOT NULL, `user_name` VARCHAR(45) NOT NULL, `password` VARCHAR(45) NOT NULL, `create_time` TIMESTAMP NULL, `update_time` TIMESTAMP NULL, PRIMARY KEY (`id`), KEY `user_name` (`user_name`), KEY `create_time` (`create_time`) )ENGINE = MyISAM; CREATE TABLE `user2` like user1; CREATE TABLE `user3` like user1;
- 创建user总表
CREATE TABLE `users` ( `id` INT NOT NULL, `user_name` VARCHAR(45) NOT NULL, `password` VARCHAR(45) NOT NULL, `create_time` TIMESTAMP NULL, `update_time` TIMESTAMP NULL, PRIMARY KEY (`id`), KEY `user_name` (`user_name`), KEY `create_time` (`create_time`) )ENGINE = MERGE UNION = (`user1`,`user2`,`user3`);
- or
CREATE TABLE users like user1;
ALTER TABLE users ENGINE=MERGE UNION(`user1`,`user2`,`user3`) insert_method=no;
可经过查看users表文件查看是否关联成功,如:html
cat /var/lib/mysql/test/users.MRG
如何操做MERGE表的数据
- 插入(INSERT)数据时,须要根据给定的路由策略将新数据分别插入不一样的子表,此处采用对id进行模3计算(可能结果为0、一、2)来决定插入哪一个子表。
- 首先,应当获取id,这个id应当在各个子表中都是惟一的,咱们须要一张表来专门建立id,执行如