MyCAT枚举分片规则 & childTable

简介:

一、MyCAT 简介和原理

  MYCAT基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广泛融入到MYCAT的基因中,使得MYCAT在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。MyCAT作为通用代理设计的,后端是以 Mysql协议 和 JDBC 的方式连接数据库,可以支持 Oracle、DB2、SQL Server 、 mongodb、mysql

这里简单分享一下  Mycat  中的概念及配置的相关基础 ,详细内容可以参考  官方文档  、  Mycat-Server  和  Get Start

数据库中间件

Mycat 其实只是一个数据中间件,或数据库代理
Tip:  所有难搞定的事情都可以通过中间件有效处理,中间件能有效解耦并专注于特定领域问题, LVM、LVS、MQ  都是这个思路(房屋中介,银行也都是这个思路)
所以Mycat没有存储引擎,本身并不存储数据,只是起到了请求分析,拆解,路由与结果聚合的作用,为前端应用提供统一接口,Mycat 与后端的数据库集群有机组合才一起构成一个分布式数据库系统

逻辑库(schema)

类似于LVM中VG的概念(VG由一个或多个PV构成),逻辑库是由一个或多个后端数据库构成的,展示给应用的是一个单一视图,是分布式数据库在逻辑上的一个抽象

逻辑表(table)

  • 逻辑表
与数据库中表相对应的,分布式数据表在逻辑上的一个抽象
  • 分片表
数据表切分后的一个部分(原表的一个真子集)
  • 非分片表
没有分片的表,就是非分片表
  • ER表
保留了实体关系特性的表,就是ER表
关系型数据库是基于实体关系模型的相关理论来构建的数据库,表与表间有依赖关系,通过表分组(Table Group) 让有依赖的表在同一实例库中从而避免了数据Join不会跨库操作
  • 全局表
全局表是所有分片上都有一份完整拷贝的表
字典表或符合字典特性的表可以被设置为全局表
有以下特点的表,被称作字典表:
  • 变动不频繁
  • 数据量总体变化不大
  • 数据规模不大(很少超过十万条记录)
  • 会与其它表发生关联
这类表可以通过冗余来解决join问题,也就是所有的分片都放上一份数据的拷贝来避免跨分片联查
Tip:  数据冗余和表分组是解决跨分片数据join的好思路,也是数据切分规划的重要规则

二、MyCAT使用测试

1、背景:schem.xml文件父表和子表,以及使用枚举分片规则
    #vim ./schema.xml    
          
                    <table name="customer" primaryKey="ID" dataNode="dn1,dn2"
                           rule="sharding-by-intfile">
                        <childTable name="orders" primaryKey="ID" joinKey="customer_id"
                                                parentKey="id">
                                <childTable name="order_items" joinKey="order_id"
                                                        parentKey="id" />
                        </childTable>
                        <childTable name="customer_addr" primaryKey="ID" joinKey="customer_id"
                                                parentKey="id" />
                </table>

     #vim ./rule.xml
                                   <tableRule name="sharding-by-intfile">
                                                    <rule>
                                                            <columns>sharding_id</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>
                                </function>
     #vim partition-hash-int.txt
                                 1=0
                                 2=1
                                 10000=0
                                 10010=1

2、登陆mycat后分别建立对应的表以及插入数据
mycat@TESTDB 08:08:56>show create table customer ;
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| customer | CREATE TABLE `customer` (
  `SHARDING_ID` int(11) DEFAULT NULL,
  `id` int(11) NOT NULL,
  `customer_id` int(11) DEFAULT NULL,
  `order_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mycat@TESTDB 07:19:09>insert into customer (SHARDING_ID, id ,customer_id,order_id) values (1,1,1,1);
Query OK, 1 rows affected (0.05 sec)

mycat@TESTDB 07:19:09>insert into customer (SHARDING_ID, id ,customer_id,order_id) values  (2,2,2,2);
Query OK, 1 rows affected (0.05 sec)

mycat@TESTDB 07:54:27>select * from customer ;
+-------------+----+-------------+----------+
| SHARDING_ID | id | customer_id | order_id |
+-------------+----+-------------+----------+
|           2 |  2 |           2 |        2 |
|           1 |  1 |           1 |        1 |
+-------------+----+-------------+----------+
2 rows in set (0.02 sec)

mycat@TESTDB 07:43:10>show create table orders ;
+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                                                                                                 |
+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| orders | CREATE TABLE `orders` (
  `SHARDING_ID` int(11) DEFAULT NULL,
  `id` int(11) NOT NULL,
  `customer_id` int(11) DEFAULT NULL,
  `customer_name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
    
mycat@TESTDB 07:43:57>insert into orders (SHARDING_ID, id , customer_id ,customer_name) values (1,1,1,'qw');
Query OK, 1 row affected (0.24 sec)

mycat@TESTDB 07:44:39>insert into orders (SHARDING_ID, id , customer_id ,customer_name) values (1,2,1,'qw');
Query OK, 1 row affected (0.25 sec)

mycat@TESTDB 07:44:45>insert into orders (SHARDING_ID, id , customer_id ,customer_name) values (1,3,1,'qw');
Query OK, 1 row affected (0.24 sec)

mycat@TESTDB 07:44:45>insert into orders (SHARDING_ID, id , customer_id ,customer_name) values (1,3,3,'qw');
ERROR 1064 (HY000): can't find (root) parent sharding node for sql:insert into orders(SHARDING_ID,id,customer_id,customer_name) values (1,3,3,'qw')

mycat@TESTDB 07:45:50>select * from orders ;
+-------------+----+-------------+---------------+
| SHARDING_ID | id | customer_id | customer_name |
+-------------+----+-------------+---------------+
|                    2 |  1 |                 1 | qw           |
|                    2 |  2 |                 2 | qw           |
|                    1 |  3 |                 2 | qw           |
+-------------+----+-------------+---------------+
3 rows in set (0.01 sec)

mycat@TESTDB 07:53:01>show create table order_items;
+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table       | Create Table                                                                                                                                                                       |
+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| order_items | CREATE TABLE `order_items` (
  `SHARDING_ID` int(11) DEFAULT NULL,
  `order_id` int(11) DEFAULT NULL,
  `order_name` varchar(15) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mycat@TESTDB 07:53:59>insert into order_items (SHARDING_ID, order_id ,order_name) values (1,1,'qw');
Query OK, 1 row affected (0.05 sec)

mycat@TESTDB 07:55:17>insert into order_items (SHARDING_ID, order_id ,order_name) values (1,2,'qw');
Query OK, 1 row affected (0.07 sec)

mycat@TESTDB 07:55:30> insert into order_items (SHARDING_ID, order_id ,order_name) values (1,3,'qw');
Query OK, 1 row affected (0.07 sec)

mycat@TESTDB 07:55:52>insert into order_items (SHARDING_ID, order_id ,order_name) values (1,4,'qw');
ERROR 1064 (HY000): can't find (root) parent sharding node for sql:insert into order_items(SHARDING_ID,order_id,order_name) values (1,4,'qw')

mycat@TESTDB 07:56:21>select * from order_items ;
+-------------+----------+------------+
| SHARDING_ID | order_id | order_name |
+-------------+----------+------------+
|                1 |               2 | qw        |
|                1 |               3 | qw        |
|                1 |               1 | qw        |
+-------------+----------+------------+
3 rows in set (0.02 sec)

mycat@TESTDB 08:09:45> show create table customer_addr ;
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table         | Create Table                                                                                                                                                                               |
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| customer_addr | CREATE TABLE `customer_addr` (
  `SHARDING_ID` int(11) DEFAULT NULL,
  `customer_id` int(11) DEFAULT NULL,
  `customer_name` varchar(15) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mycat@TESTDB 07:57:59>insert into customer_addr (SHARDING_ID, customer_id ,customer_name) values (1,1,'qw');
Query OK, 1 row affected (0.26 sec)

mycat@TESTDB 07:58:28>insert into customer_addr (SHARDING_ID, customer_id ,customer_name) values (1,2,'qw');
Query OK, 1 row affected (0.05 sec)

mycat@TESTDB 07:58:32>insert into customer_addr (SHARDING_ID, customer_id ,customer_name) values (1,3,'qw');
ERROR 1064 (HY000): can't find (root) parent sharding node for sql:insert into customer_addr(SHARDING_ID,customer_id,customer_name) values (1,3,'yue')

mycat@TESTDB 08:04:42>select * from customer_addr;
+-------------+----+-------------+---------------+
| SHARDING_ID | id | customer_id | customer_name |
+-------------+----+-------------+---------------+
|           1 |  1 |           1 | qw            |
|           1 |  2 |           2 | qw            |
|           1 |  3 |           2 | qw            |
+-------------+----+-------------+---------------+
3 rows in set (0.01 sec)


3、分片表子表配置 childTable标签:
20160224092521012
  1. name属性
  2. joinKey属性:插入子表的时候会使用这个列的值查找父表存储的数据节点。
  3. parentKey属性:属性指定的值一般为与父表建立关联关系的列名。程序首先获取joinkey的值,再通过parentKey属性指定的列名产生查询语句,通过执行该语句得到父表存储在哪个分片上。从而确定子表存储的位置。
  4. primaryKey属性:同table标签所描述的。
  5. needAddLimit属性:同table标签所描述的。
总结:子表中的 joinKey="***_id" 字段取值取决于父表 primaryKey="ID"中的值,不然会报错(简单说 joinKey是 primaryKey的外键
目录
相关文章
|
4月前
|
算法 数据库
Mycat【Mycat分片规则(取模、分片枚举、范围约定)】(六)-全面详解(学习总结---从入门到深化)
Mycat【Mycat分片规则(取模、分片枚举、范围约定)】(六)-全面详解(学习总结---从入门到深化)
83 0
|
11月前
|
存储 SQL 缓存
27MyCat - 分片规则
27MyCat - 分片规则
36 0
|
11月前
28MyCat - 分片规则(分片枚举)
28MyCat - 分片规则(分片枚举)
25 0
|
11月前
35MyCat - 分片规则(字符串hash解析)
35MyCat - 分片规则(字符串hash解析)
69 0
|
11月前
34MyCat - 分片规则(应用指定)
34MyCat - 分片规则(应用指定)
40 0
|
11月前
32MyCat - 分片规则(取模范围约束)
32MyCat - 分片规则(取模范围约束)
30 0
|
11月前
31MyCat - 分片规则(按日期分片)
31MyCat - 分片规则(按日期分片)
40 0
|
11月前
30MyCat - 分片规则(求模)
30MyCat - 分片规则(求模)
18 0
|
11月前
38MyCat - 分片规则(自然月分片)
38MyCat - 分片规则(自然月分片)
45 0
|
11月前
|
数据处理 数据库
08MyCat - 概念 - 分片节点、分片规则、全局序列号
08MyCat - 概念 - 分片节点、分片规则、全局序列号
42 0