MyCAT ER分片的驗證


在這里,構造了兩張表,熟悉Oracle的童鞋都知道,dept(部門表)和emp(員工表),其中dept中的deptno是emp表中dept_no的外鍵。

兩表的建表語句如下:

create table dept(deptno int,dname varchar(10),datanode varchar(10));

create table emp(empno int,dept_no int,datanode varchar(10));

注意:在這里,最后一列都是datanode,通過插入database()函數可以很直觀的獲取插入的節點名,從而驗證分片的效果。

分別測試以下兩種情況:

1. 父表按照主鍵ID分片,子表的分片字段與主表ID關聯,配置為ER分片
2. 父表的分片字段為其他字段,子表的分片字段與主表ID關聯,配置為ER分片

首先測試第一種情況,在這里,dept表作為父表,主鍵是deptno,empno為子表,關聯字段為dept_no,分片字段為deptno。

schema.xml中的配置如下:

 <table name="dept" primaryKey="deptno" dataNode="dn1,dn2,dn3"
                rule="sharding-by-intfile">
                <childTable name="emp" primaryKey="empno" joinKey="dept_no"
                                parentKey="deptno">
                        </childTable>
  </table>

rule.xml中的配置如下:

 <tableRule name="sharding-by-intfile">
                <rule>
                        <columns>deptno</columns>
                        <algorithm>hash-int</algorithm>
                </rule>
        </tableRule>

修改很簡單,就是將原來的id修改為deptno,代表分片的字段

 partition-hash-int.txt的值修改為:

10=0

20=1

 

驗證如下:

插入父表的值,

datanode為db1,與partition-hash-int.txt中的配置相符

mysql> insert into dept(deptno,dname,datanode) values(10,'ACCOUNTING',database());
Query OK, 1 row affected (0.05 sec)

mysql> select * from dept;
+--------+------------+----------+
| deptno | dname      | datanode |
+--------+------------+----------+
|     10 | ACCOUNTING | db1      |
+--------+------------+----------+
1 row in set (0.12 sec)

日志輸出信息如下:

接下來插入子表的值

mysql> insert into emp(empno,dept_no,datanode) values(7788,10,database());
Query OK, 1 row affected (0.01 sec)

日志輸出信息如下:

關鍵點在於“using parent partion rule directly”。意思是直接使用父的分片規則。如果表本身並沒有指定外鍵約束。

則即便父並沒有相應的主鍵值,子表依舊可以插入,只要分片規則中有所定義。

如下所示:

mysql> select * from emp;
+-------+---------+----------+
| empno | dept_no | datanode |
+-------+---------+----------+
|  7788 |      10 | db1      |
+-------+---------+----------+
1 row in set (0.52 sec)

mysql> select * from dept;
+--------+------------+----------+
| deptno | dname      | datanode |
+--------+------------+----------+
|     10 | ACCOUNTING | db1      |
+--------+------------+----------+
1 row in set (0.13 sec)

mysql> insert into emp(empno,dept_no,datanode) values(1234,20,database());
Query OK, 1 row affected (0.09 sec)

盡管dept中沒有deptno為20的行。

但emp還是能插入dept_no為20的值

日志的輸出信息如下:

所以,對於第一種情況,即父表按照主鍵分片,字表的分片字段與主表關聯,結論就是,子表進行insert操作時,並不會檢查父表中是否有相關的主鍵(對於子表的外鍵),而是直接根據分片規則進行判斷。

如果分片規則中沒有定義,則會報如下錯誤:

mysql> insert into emp(empno,dept_no,datanode) values(1234,30,database());
ERROR 1064 (HY000): can't find datanode for sharding column:DEPTNO val:30

 

2. 父表的分片字段為其他字段,子表的分片字段與主表ID關聯,配置為ER分片

在這里,打算用dname作為分片字段,這樣的話,只需要修改route.xml和partition-hash-int.txt了。

首先,修改rule.xml

<tableRule name="sharding-by-intfile">
                <rule>
                        <columns>dname</columns>
                        <algorithm>hash-int</algorithm>
                </rule>
        </tableRule>
<function name="hash-int"
                class="org.opencloudb.route.function.PartitionByFileMap">
                <property name="mapFile">partition-hash-int.txt</property>
                <property name="type">1</property>
        </function>

因dname是字符類型,故將type設置為1。

接着,修改算法配置文件的值

[root@mysql-server1 conf]# cat partition-hash-int.txt 
accounting,research=0
sales=1
operations=2

登錄mycat管理端口,重新加載配置文件

[root@mysql-server1 conf]# mysql -h192.168.244.145 -utest -ptest -P9066

mysql> reload @@config;
Query OK, 1 row affected (0.14 sec)
Reload config success

現在進行測試:

mysql> insert into dept(deptno,dname,datanode) values(10,'accounting',database());
Query OK, 1 row affected (0.14 sec)
mysql> insert into emp(empno,dept_no,datanode) values(1234,10,database());
Query OK, 1 row affected (0.29 sec)

日志的輸出信息如下:

插入第二個分區中的值

mysql> insert into dept(deptno,dname,datanode) values(20,'sales',database());
Query OK, 1 row affected (0.01 sec)

mysql> insert into emp(empno,dept_no,datanode) values(1234,20,database());
Query OK, 1 row affected (0.41 sec)

日志的輸出信息如下:

這次是在兩個分區查找子表的分區節點

插入第三個分區中的值

mysql>  insert into dept(deptno,dname,datanode) values(30,'operations',database());
Query OK, 1 row affected (0.00 sec)

mysql> insert into emp(empno,dept_no,datanode) values(4567,30,database());
Query OK, 1 row affected (0.62 sec)

日志的輸出信息如下:

在三個分區中查找子表的分區節點

總結:在父表的分片字段為其他字段,子表的分片字段與主表ID關聯這種情況下,子表的分區節點是順序查找的,在該例中,依次從dn1,dn2和dn3中查找,如果dn1中存在,就直接插入到dn1中,反之,則繼續查找dn2節點,如果仍不存在,則繼續在dn3節點中查找。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM