(1) 数据分片的实现
Mycat通过加载schema.xml中的配置信息,实现对数据的分片处理,schema.xml中的具体配置信息如下:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
<table name="tb_user" primaryKey="user_id" dataNode="dn1,dn2" rule="mod-long">
<childTable name="orders" joinKey="user_id" parentKey="user_id"/>
</table>
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="root">
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
</mycat:schema>
从代码中可以看出,tb_user表和orders表存放于结点dn1和dn2上,因为用户和订单之间存在着关联关系,故可将这部分配置为父子表关系,tb_user配置为父表,orders表配置为子表,通过user_id字段连接,采用的是取模分片算法进行的数据分片,rule="mod-long"的定义是在conf文件夹下的rule.xml文件中进行配置的,默认使用的是模3分片,这里修改为模2分片,取模结果等于0时,数据存放于dn1结点上,取模结果等于1时,数据存放于dn2上,修改代码如下:
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">2</property>
</function>
(2) 数据准备
根据上面的配置文件,我们需要分别在db1和db2两个数据库上新建两张名为tb_user和orders的表,使用Navicat打开命令界面创建表,并向表中添加数据,创建表的命令如下:
CREATE TABLE orders ( order_id INT NOT NULL PRIMARY KEY, order_name VARCHAR ( 100 ), user_id INT NOT NULL );
CREATE TABLE tb_user( user_id INT NOT NULL PRIMARY KEY, user_name VARCHAR ( 100 ));
(3) 跨库查询的实现
比如,对tb_user和orders的跨库连接查询条件中包含user_id=3,因为user_id%2=1,所以会从dn2节点中进行局部连接查询,获取查询结果,结果如下:
EXPLAIN SELECT u.user_name,o.order_name FROM tb_user u,orders o WHERE u.user_id = 3 AND u.user_id = o.user_id;
结果如下图所示: