mycat分库分表
Mycat2 一大优势就是可以在终端直接创建数据源、集群、库表,并在创建时指定 分库、分表。
操作之前,请先启动一主一从的mysql服务,启动mycat服务
以下步骤不是必须,看自己情况操作
注:前面由于搭建过双主双从的服务,为了方便,本文档教程不使用双主双从,使用一主一从演示就够了,然后mycat里面配置的另外的mysql数据源文件需要更改名称或者直接删除,不然mycat启动会加载,加载不成功就会报错导致mycat无法启动成功
修改clusters
路径的集群配置,去除不要的数据源
修改datasources
路径的数据源配置,去除不要的数据源
1.添加数据库,数据源
使用注解的方式
在mycat里面执行,直接用navicat连接mycat,在navicat里面执行就行
-- 数据库连接信息需要替换成自己的-- 注意name和url的信息-- 共创建了四个数据源,两个数据库服务分别创建一读一写的数据源,实际中为了更好的效率,每个数据源应该是单独的mysql数据库服务,这里为了方便没使用那么多mysql服务-- 写数据源1/*+ mycat:createDataSource{"name":"dw0","url":"jdbc:mysql://192.168.171.142:3306","user":"root","password":"root"} */;-- 读数据源1/*+ mycat:createDataSource{"name":"dr0","url":"jdbc:mysql://192.168.171.142:3306","user":"root","password":"root"} */;-- 写数据源2/*+ mycat:createDataSource{"name":"dw1","url":"jdbc:mysql://192.168.171.143:3306","user":"root","password":"root"} */;-- 数读据源1/*+ mycat:createDataSource{"name":"dr1","url":"jdbc:mysql://192.168.171.143:3306","user":"root","password":"root"} */;
查看数据源:
/*+ mycat:showDataSources{} */;
查看mycat的conf/datasources
路径,也可以看到生成的数据源文件
2.添加集群配置
将上一步创建好的四个数据源配置成集群
-- 集群名字推荐以c开头,c0,c1....-- 在masters和replicas属性里面配置创建好的数据源名称-- 集群一/*!mycat:createCluster{"name":"c0","masters":["dw0"],"replicas":["dr0"]}*/;-- 集群2/*!mycat:createCluster{"name":"c1","masters":["dw1"],"replicas":["dr1"]}*/;
查看集群
/*+ mycat:showClusters{} */;
查看mycat的conf/clusters
路径,也可以看到生成的集群文件
3.创建全局表
全局表就是完整的存在于多个库中,每个mysql服务中都有这张表,通常是字典表,配置表等。
-- 以下SQL是在mycat中执行的,不是mysql-- 添加数据库db1create database db1;-- 创建全局表,建表语句同mysql一模一样,就是多了一个关键字BROADCASTCREATE TABLE db1.`travelrecord` (`id` bigint NOT NULL AUTO_INCREMENT,`user_id` varchar(100) DEFAULT NULL,`traveldate` date DEFAULT NULL,`fee` decimal(10,0) DEFAULT NULL,`days` int DEFAULT NULL,`blob` longblob,PRIMARY KEY (`id`),KEY `id` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 BROADCAST;
执行完成后,可以在mycat、mysql中看到新建的数据库及全局表
同样,进去到conf/schema
目录,也可以看到新生成的json文件:
关于绑定的集群这样解释也不知道对不对,反正创建数据库后mycat确实是自动帮我们关联上了
4.创建分片表(分库分表)
-- 以下SQL是在mycat中执行的,不是mysqlCREATE TABLE db1.orders(id BIGINT NOT NULL AUTO_INCREMENT,order_type INT,customer_id INT,amount DECIMAL(10,2),PRIMARY KEY(id),KEY `id` (`id`))ENGINE=INNODB DEFAULT CHARSET=utf8 dbpartition BY mod_hash(customer_id) tbpartition BY mod_hash(customer_id) tbpartitions 1 dbpartitions 2;
mod_hash:分片规则,里面值为字段,表示根据哪个字段进行取模哈希,然后分片数据
tbpartitions 1 dbpartitions 2:表示分成2个库,每个库各1张表,具体要分多少库,每个库分多少表更改数字大小就行
再去查看db1.schema.json
文件,会看到新增的配置信息
现在,往新建的表中插入数据
-- 在mycat中执行INSERT INTO db1.orders(id,order_type,customer_id,amount)VALUES(1,101,100,100100);INSERT INTO db1.orders(id,order_type,customer_id,amount)VALUES(2,101,100,100300);INSERT INTO db1.orders(id,order_type,customer_id,amount)VALUES(3,101,101,120000);INSERT INTO db1.orders(id,order_type,customer_id,amount)VALUES(4,101,101,103000);INSERT INTO db1.orders(id,order_type,customer_id,amount)VALUES(5,102,101,100400);INSERT INTO db1.orders(id,order_type,customer_id,amount)VALUES(6,102,100,100020);
插入数据完成后,执行下查询SQL
-- 在mycat中执行select * from orders;
六条数据都完整的正常查询出来了;这时候,再去两个mysql服务中的分库里面查看下:
但是,在mycat服务里面经过验证,执行select * from orders
是可以查询到全部的6条数据
5.创建ER表
与分片表关联的表如何分表,也就是ER表如何分表,如下:
-- 在mycat中执行CREATE TABLE orders_detail(`id` BIGINT NOT NULL AUTO_INCREMENT,detail VARCHAR(2000),order_id INT,PRIMARY KEY(id))ENGINE=INNODB DEFAULT CHARSET=utf8 dbpartition BY mod_hash(order_id) tbpartition BY mod_hash(order_id)tbpartitions 1 dbpartitions 2;
插入数据
INSERT INTO orders_detail(id,detail,order_id) VALUES(1,'detail1',1);INSERT INTO orders_detail(id,detail,order_id) VALUES(2,'detail1',2);INSERT INTO orders_detail(id,detail,order_id) VALUES(3,'detail1',3);INSERT INTO orders_detail(id,detail,order_id) VALUES(4,'detail1',4);INSERT INTO orders_detail(id,detail,order_id) VALUES(5,'detail1',5);INSERT INTO orders_detail(id,detail,order_id) VALUES(6,'detail1',6);
然后,自行验证查询数据是否插入成功,仔细看的话会发现同一个库里面表的关联字段,即orders_detail
表的order_id
字段值有的并不存在当前库的orders
表中
创建的分片表和ER表,即本次演示中创建的orders
和orders_detail
表,在创建的时候具有相同的分片算法,但是分片的字段不一样,orders
用的是customer_id
字段,orders_detail
用的是order_id
字段
Mycat2无需指定ER表,会自动识别的,使用注解查看是否具有ER关系
/*+ mycat:showErGroup{}*/
group_id 表示相同的组,该组中的表具有ER关系
执行sql,实现join关联查询语句
-- 在mycat中执行SELECT * FROM orders o INNER JOIN orders_detail od ON od.order_id=o.id;
可完美的实现联表查询,mycat将分布在两个mysql服务中查到的数据结果合并
.(img-HEv9rIse-1658479874628)]
group_id 表示相同的组,该组中的表具有ER关系
执行sql,实现join关联查询语句
-- 在mycat中执行SELECT * FROM orders o INNER JOIN orders_detail od ON od.order_id=o.id;
可完美的实现联表查询,mycat将分布在两个mysql服务中查到的数据结果合并