mycat E-R關系分片策略測試
阿新 • • 發佈:2018-01-09
lns 由來 native with hose 設計 localhost local XML 1.E-R關系策略的由來
join是關系數據庫最常用的一個特性,然而在分布式環境中,跨分片的join最復雜,最難解決。
這是官方文檔的描述。
具體點,比如:
mycat邏輯庫hello,兩張表格t1,t2。做了分庫策略,t1放到了datanode1,t2放到了datanode2。如果我t1 join t2檢索數據,
怎麽辦?
這就是E-R關系策略要解決的問題。
mycat借鑒了table group的概念,將子表的存儲位置依賴於子表,並且在物理上緊鄰存放,解決了join的效率和性能問題。E-R關系的數據分片策略,根據這一思路,將子表的記錄和所關聯的父表記錄存放在同一個數據分片上。
2.測試官方教程文檔上的E-R關系表
customer采用sharding-by-intfile(分片枚舉)策略,分片在dn1,dn2上,orders依賴父表進行分片,兩個表的關聯關系為orders.customer_id=customer.id。示意圖如下:
![](http://i2.51cto.com/images/blog/201712/21/1298cf4400570a0d5bcc4bdd40070e27.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
<table name="customer" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile">
<childTable name="orders" joinKey="customer_id" parentKey="id"/>
</table>
解釋:
<table name="customer" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile">
這一行是定義customer表,主鍵是id,分片部署在dn1,dn2,分片規則是sharding-by-intfile
<childTable name="orders" joinKey="customer_id" parentKey="id"/>
這一行是定義orders是childtable。
childtable是依賴父表的結構,就是前面時候的E-R關系的表。
childtable的joinkey會按照父表的parentkey一起切分。
</table>
這是對應 <table name= 的結束格式,參考xml格式。
3.
表格設計:
customer表
id(primarykey) name city (用city做分片)
orders表
customer_id(primary key) orders
兩表格關系:
customer表的主鍵id為orders表主鍵customer_id的外鍵
4.mycat上實際測試:
停止mycat服務,修改配置文件,如下:
[root@ha1 conf]# cat schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="hello" checkSQLschema="false" sqlMaxLimit="100">
<!-- auto sharding by id (long) -->
<table name="t1" dataNode="dn1,dn2" rule="sharding-by-intfile" />
<!-- global table is auto cloned to all defined data nodes ,so can join
with any table whose sharding node is in the same data node -->
<table name="t2" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<table name="t3" dataNode="dn1" />
<table name="t4" dataNode="dn2" />
<table name="customer" primaryKey="id" dataNode="dn1,dn2"
rule="sharding-by-intfile">
<childTable name="orders" joinKey="customer_id" parentKey="id"/>
</table>
</schema>
<!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
/> -->
<dataNode name="dn1" dataHost="mysql1" database="db1" />
<dataNode name="dn2" dataHost="mysql3" database="db2" />
<dataHost name="mysql1" maxCon="1000" minCon="10" balance="3"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="192.168.211.138:3306" user="root"
password="Alex2010@">
</writeHost>
<writeHost host="hostS1" url="192.168.211.139:3306" user="root"
password="Alex2010@">
</writeHost>
</dataHost>
<dataHost name="mysql3" 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="192.168.211.142:3306" user="root"
password="Alex2010@">
<!-- can have multi read hosts -->
<readHost host="hostS2" url="192.168.211.142:3306" user="root" password="Alex2010@"/>
</writeHost>
</dataHost>
</mycat:schema>
定義分片規則:
<tableRule name="sharding-by-intfile">
<rule>
<columns>city</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<function name="hash-int"
class="io.mycat.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
<property name="type">1</property>
<property name="defaultNode">0</property>
</function>
[root@ha2 conf]# cat partition-hash-int.txt
gz=0
sz=1
啟動mycat,創建表格:
mysql> create table customer(id int not null primary key,name varchar(10),city varchar(20));
Query OK, 0 rows affected (0.11 sec)
mysql> create table orders (customer_id int not null primary key,orders int not null,foreign key(customer_id) references customer(id)
on delete cascade on update cascade);
Query OK, 0 rows affected (0.25 sec)
customer插入數據測試:
mysql> insert into customer(id,name,city) values(1,'am1','gz'),(2,'am2','gz'),(3,'am3','sz');
mysql> select * from customer where city='gz';
+----+------+------+
| id | name | city |
+----+------+------+
| 1 | am1 | gz |
| 2 | am2 | gz |
+----+------+------+
2 rows in set (0.08 sec)
mysql> explain select * from customer where city='gz';
+-----------+----------------------------------------------------+
| DATA_NODE | SQL |
+-----------+----------------------------------------------------+
| dn1 | SELECT * FROM customer WHERE city = 'gz' LIMIT 100 |
+-----------+----------------------------------------------------+
1 row in set (0.01 sec)
gz的數據都在dn1實現了分片。
orders插入數據測試:
mysql> insert into orders(customer_id,orders) values(1,10001);
Query OK, 1 row affected (0.33 sec)
mysql> insert into orders(customer_id,orders) values(2,10002);
Query OK, 1 row affected (0.29 sec)
mysql> insert into orders(customer_id,orders) values(3,10003);
Query OK, 1 row affected (0.48 sec)
根據E-R分片規則,orders表格根據外鍵的值也就是customer的主鍵值切分,
也就是orders.customer_id=customer.id的數據分在一個區。
分別在db1,db2檢索數據,看看是否達到E-R分片的設計要求。
mycat E-R關系分片策略測試