环境:master:192.168.225.128 slave:192.168.225.129
master和slave上面各有两个数据库db01,db02。users表存放在db01,db02中都有,但是不做分表,查询随机发送到哪台服务器。item表其中一部分数据存放在master的db02中,另一部分数据存放在slave的db02中。
item_detail依赖父表进行分片(也即E-R分片策略),两个表的关联关系为t_user_detail.user_id=t_user.id。分片规则用取模的方式,如果在分表的时候还要做读写分离,只需要在writeHost下面添加readhost选项即可。
1,mycat安装部署
参考上一篇博文:
link
2,修改配置文件
[root@slave conf]# cat schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 设置表的存储方式.schema name="TESTDB" 与 server.xml中的 TESTDB 设置一致 -->
<schema name="MYDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- global表示全局表,即表示users表所有记录都在node_db01中,不做拆分,如果user表很小,当业务需要这个表和其他大表进行join的时候,也可以-->
<!--将这个users表在每个库中都保存一份,只需要在node_db01后面添加其他的库名即可。-->
<table name="users" primaryKey="id" type="global" dataNode="node_db01" />
<table name="item" primaryKey="id" dataNode="node_db02,node_db03" rule="mod-long">
<childTable name="item_detail" primaryKey="id" joinKey="item_id" parentKey="id" />
</table>
</schema>
<!-- 设置dataNode 对应的数据库,及 mycat 连接的地址dataHost -->
<dataNode name="node_db01" dataHost="dataHost01" database="db01" />
<dataNode name="node_db02" dataHost="dataHost01" database="db02" />
<dataNode name="node_db03" dataHost="dataHost02" database="db02" />
<!-- mycat 逻辑主机dataHost对应的物理主机.其中也设置对应的mysql登陆信息 -->
<dataHost name="dataHost01" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="slave" url="192.168.225.129:3306" user="root" password="123456"/>
</dataHost>
<dataHost name="dataHost02" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="192.168.225.128:3306" user="root" password="123456"/>
</dataHost>
</mycat:schema>
3,测试:
create database db01;
create database db02;
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL default '',
indate DATETIME default null,
PRIMARY KEY (id)
)AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE item (
id INT NOT NULL AUTO_INCREMENT,
value INT NOT NULL default 0,
indate DATETIME default NULL ,
PRIMARY KEY (id)
)AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE item_detail (
id INT NOT NULL AUTO_INCREMENT,
value INT NOT NULL default 0,
name varchar(50) NOT NULL default '',
item_id INT NOT NULL,
PRIMARY KEY (id),
key (item_id)
)AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
#mysql -umy -p123456 -h192.168.225.129 -P8066
>insert into item(id,value,indate) values(1,100,now());
>insert into item_detail(value,name,item_id) values('40','pad',1);
>insert into item(id,value,indate) values(2,100,now());
>insert into item_detail(value,name,item_id) values('50',phone,2);
*实际生产环境:
** 在实际中ip1和ip2是主从关系,假设dataHost01对应db1,dataHost02对应db2,这样ip1和ip2中存储了db1的分片数据,ip3中存储了db2的分片数据,在写操作的时候,mycat会将对应数据写入ip1,通过主从通过到ip2, 另一部分数据写入ip3
在读操作的时候,mycat会从ip2和ip3中获取对应数据合并后返回客户端。配置如下:
<!-- mycat 逻辑主机dataHost对应的物理主机.其中也设置对应的mysql登陆信息 -->
<dataHost name="dataHost01" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="slave" url="192.168.225.129:3306" user="root" password="123456"/>
<readHost host="third" url="192.168.225.130:3009" user="root" password="123456"/>
</dataHost>
<dataHost name="dataHost02" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="192.168.225.128:3306" user="root" password="123456"/>
</dataHost>
</mycat:schema>