Mycat是什么?是数据库中间件,介于数据库与应用之间,进行数据处理与交互的中间件服务,可以简单的理解成数据库代理,我们的应用只需要与数据库中间件交互,而无需关注复杂的数据库部署。
如上图所示,数据被分到多个分片数据库后,应用如果需要读取数据,就需要处理多个数据源的数据。如果没有数据库中间件,那么应用将直接面对分片集群,数据源切换、事务处理、数据聚合都需要在应用层直接处理,原本该是专注于业务的应用,将会花大量的工作来处理分片后的问题,最重要的是每个应用处理将是完全的重复造轮子。所以有了数据库中间件,应用只需要关注业务处理,大量的通用的数据聚合、事务、数据源切换都由数据库中间件来处理。
其前身是阿里的cobar
1.2 干什么的 1.2.1 读写分离- 垂直拆分
- 水平拆分
- 垂直+水平拆分
这种方式把数据库的分布式从代码中解耦出来,程序员察觉不出来后台使用mycat还是mysql。
二、安装启动 2.1 解压缩文件拷贝到linux下/user/local/目录- schema.xml:定义逻辑库,表、分片节点等内容。
- rule.xml:定义分片规则。
- server.xml:定义用户以及系统相关变量,如端口等。
select user()
mysql -uroot -p123123 -h 192.168.154.1 -P 3306
mysql -uroot -p123123 -h 192.168.154.154 -P 3306
如本机远程访问报错,请建对应用户
grant all privileges on *.* to root@'缺少的host' identified by '123123';
2.6 启动程序
控制台启动:去mycat/bin目录下mycat console
后台启动:去mycat/bin目录下mycat start
域名解析失败
1.用vim修改/etc/hosts文件
2.修改后重新启动网络服务
mysql -uroot -p123456 -P9066 -h192.168.67.131
命令:show @@help
2.8.2 数据窗口
mysql -uroot -p123456 -P8066 -h192.168.67.131
三、读写分离 3.1 schema.xm此处balance由0改为2,让其随机分配,测试效果,然后执行./mycat console重启服务。
3.2 读写分离1.创建表
create table t_replica
( id int auto_increment ,
name varchar(200)
);
分别在两个库下插入:
insert into t_replicat(name) values (@@hostname)
然后在mycat下执行select * from t_replica能够看出区别
四、分库 4.1 分库 配置在dn2上创建customer表,剩下的在dn1上面
分别在两天直接创建数据库,order190401,然后./mycat console重启mycat
4.2 通过mycat建表#客户表 rows:20万
CREATE TABLE customer(
id INT AUTO_INCREMENT,
NAME VARCHAR(200),
PRIMARY KEY(id)
);
#订单表 rows:600万
CREATE TABLE orders(
id INT AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id)
);
#订单详细表 rows:600万
CREATE TABLE orders_detail(
id INT AUTO_INCREMENT,
detail VARCHAR(2000),
order_id INT,
PRIMARY KEY(id)
);
#订单状态字典表 rows:20
CREATE TABLE dict_order_type(
id INT AUTO_INCREMENT,
order_type VARCHAR(200),
PRIMARY KEY(id)
);
select o.*,od.detail,d.order_type
from orders o
inner join orders_detail od on o.id =od.order_id
inner join dict_order_type d on o.order_type=d.id
where o.customer_id=xxxx
成功做了分库操作。
五、水平分表INSERT INTO orders(id,order_type,customer_id,amount) VALUES(1,101,100,100100);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(2,101,100,100300);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(3,101,101,120000);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(4,101,101,103000);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(5,102,101,100400);
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(6,102,100,100020);
原因,mycat分别从两个数据库,查询到结果,然后,union一下。如果非要按照顺序显示,可以加上order by进行排序
5.3.2 给订单详情表插入数据SELECT * FROM orders o
INNER JOIN orders_detail od ON od.order_id=o.id;
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);
跨库没办法进行关联查询join
5.4 跨库join 5.4.1 ER表为了相关联的表的行尽量分在一个库下
设定为全局的表,会直接复制给每个数据库一份,所有写操作也会同步给多个库。
所以,全局表一般不能是大数据表或者更新频繁的表。
一般是字典表或者系统表为宜。
本地文件:不推荐
数据库方式
时间戳方式:18位比较长,不对劲
5.5.2 自主生成根据业务逻辑组合
可以利用redis的单线程原子性incr来生成序列
5.5.3 数据库方式1. 数据库序列方式原理
2.建库序列脚本
win10
create table mycat_sequence (name varchar(50) not null,current_value int not
null,increment int not null default 100, primary key(name)) engine=innodb;
delimiter $$
create function mycat_seq_currval(seq_name varchar(50)) returns varchar(64)
deterministic
begin
declare retval varchar(64);
set retval="-999999999,null";
select concat(cast(current_value as char),",",cast(increment as char)) into retval from
mycat_sequence where name = seq_name;
return retval;
end $$
delimiter;
delimiter $$
create function mycat_seq_setval(seq_name varchar(50),value integer) returns varchar(64)
deterministic
begin
update mycat_sequence
set current_value = value
where name = seq_name;
return mycat_seq_currval(seq_name);
end $$
delimiter ;
delimiter $$
create function mycat_seq_nextval(seq_name varchar(50)) returns varchar(64)
deterministic
begin
update mycat_sequence
set current_value = current_value + increment where name = seq_name;
return mycat_seq_currval(seq_name);
end $$
delimiter;
select * from mycat_sequence
truncate table mycat_sequence
##增加要用的序列
insert into mycat_sequence(name,current_value,increment) values ('orders', 400000,
100);
3.修改mycat配置
sequence_db_conf.properties
server.xml
然后重启
4.插入语句
insert into `orders`(id,amount,customer_id,order_type) values(next value for MYCATSEQ_ORDERS,1000,101,102);
视频教程