MySQL中间件之MyCat

MySQL中间件之MyCat

1、MyCat基础概念

一、什么是MyCat

一个完全开源的,面向企业应用开发的大数据库集群
支持事务、ACID、能够替代MySQL的增强版数据库
一个能够视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品java

二、为何使用MyCat

现在随着互联网的发展,数据的量级也是撑指数的增加,从GB到TB到PB。对数据的各类操做也是越发的困难,传统的关系性数据库已经没法知足快速查询与插入数据的需求。这个时候NoSQL的出现暂时解决了这一危机。它经过下降数据的安全性,减小对事务的支持,减小对复杂查询的支持,来获取性能上的提高。可是,在有些场合NoSQL一些折衷是没法知足使用场景的(好比有些使用场景是绝对要有事务与安全指标的。这个时候NoSQL确定是没法知足的)。因此仍是须要使用关系性数据库。如何使用关系型数据库解决海量存储的问题呢?此时就须要作数据库集群,为了提升查询性能将一个数据库的数据分散到不一样的数据库中存储,为应对此问题就出现了——MyCatnode

MyCat做用:

能知足数据库数据大量存储;提升了查询性能
读写分离
数据分片 垂直拆分(分库)、水平拆分(分表)、垂直+水平拆分(分库分表)
多数据源整合mysql

三、 数据库中间件对比

① Cobar(前身为amoaba)属于阿里B2B事业群,始于2008年,在阿里服役3年多,接管3000+个MySQL数据库的schema, 集群日处理在线SQL请求50亿次以上。因为Cobar发起人的离职, Cobar中止维护。
② Mycat是开源社区在阿里cobar基础上进行二次开发,解决了cobar存在的问题,而且加入了许多新 的功能在其中。青出于蓝而胜于蓝。
③ OneProxy基于MySQL官方的proxy思想利用c进行开发的, OneProxy是一款商业收费的中间件。舍弃了一些功能,专一在性能和稳定性上。
④ kingshard由小团队用go语言开发,还须要发展,须要不断完善。
⑤ Vitess是Youtube生产在使用,架构很复杂。不支持MySQL原生协议,使用须要大量改形成本。
⑥ Atlas是360团队基于mysql proxy改写,功能还需完善,高并发下不稳定。
⑦ MaxScale是mariadb(MySQL原做者维护的一个版本) 研发的中间件
⑧ MySQLRoute是MySQL官方Oracle公司发布的中间件linux

四、支持的数据库

支持MySQL ORACLE SQLServer等一些主流的数据库算法

五、核心技术

分库分表:数据库分片指经过某种特定的条件,将咱们存放在一个数据库中的数据分散存放在不一样的多个数据库(主机)中,这样来达到分散单台设备的负载,根据切片规则,可分为如下两种切片模式,MyCAT经过定义表的分片规则来实现分片,每一个表格能够捆绑一个分片规则,每一个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法sql

1)Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。
2)Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不一样,这里的表格须要声明其所存储的逻辑数据节点DataNode。在此能够指定表的分片规则。
3)DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,经过DataSource来关联到后端某个具体数据库上
4)DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上
5)分片规则:前面讲了数据切分,一个大表被分红若干个分片表,就须要必定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则很是重要,将极大的避免后续数据处理的难数据库

2、MyCat安装部署

环境:

JDK:要求jdk必须是1.7及以上版本
MySQL:推荐mysql是5.5以上版本
MyCat的官方网站:http://www.mycat.org.cn/
主机 操做系统 IP地址
mysql01(master01) CentOS 7.3 192.168.1.1
mysql02(slave) CentOS 7.3 192.168.1.8
mycat CentOS 7.3 192.168.1.3
PS:mysql使用现成的主机(搭建了双主+keepalived,主从也能够)。若是没有mysql,看上一个博客部署。

一、下载及安装,使用上面的官网地址下载。

MySQL中间件之MyCat
MySQL中间件之MyCat

复制连接,wget下载vim

[root@localhost ~]# wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

MySQL中间件之MyCat

将压缩包解压缩。建议将mycat放到/usr/local/mycat目录下。后端

[root@localhost ~]# tar zxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
[root@localhost ~]# cd mycat/

修改配置文件:缓存

server.xml: 定义用户以及系统相关变量,如端口等
schema.xml: 定义逻辑库,表、分片节点等内容
rule.xml: 定义分片规则

[root@mycat mycat]# vim conf/server.xml  
80         <user name="mycat">      //定义链接中间件的用户
81                 <property name="password">123456</property>  //密码
82                 <property name="schemas">TESTDB</property>      //逻辑库
[root@mycat mycat]# cp conf/schema.xml conf/schema.xml.bak  //备份配置文件
[root@mycat mycat]# vim conf/schema.xml 
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">     //指明逻辑库,以及节点
        </schema>
        <dataNode name="dn1" dataHost="host1" database="test_db" />     //指定后端服务器中的真实库
        <dataHost name="host1" 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.1.1:3306" user="root"    //定义写的服务器(主)以及IP地址,用户密码
                                   password="123.com">
                        <!-- can have multi read hosts -->
                        <readHost host="hostS2" url="192.168.1.8:3306" user="root" password="123.com" />    //定义读的服务器(从)以及IP地址,用户密码
                </writeHost>
        </dataHost>
</mycat:schema>

##这个配置文件已经把没必要要配置项以及注释的都删了

重启mycat服务
让mycat拥有mysql命令

[root@mysql02 ~]# scp /usr/local/mysql/bin/mysql 192.168.1.3:/usr/local/sbin/

两台mysql受权,容许mycat远程登录

mysql> grant all on *.* to root@'192.168.1.%' identified by '123.com';

MyCat远程登陆测试:

[root@mycat mycat]# mysql -uroot -h 192.168.1.1 -P 3306 -p123.com
[root@mycat mycat]# mysql -uroot -h 192.168.1.8 -P 3306 -p123.com

启动mycat服务:

[root@mycat mycat]# ./bin/mycat help
Usage: ./bin/mycat { console | start | stop | restart | status | dump }
[root@mycat mycat]# ./bin/mycat console

使用console启动,会占用一个终端,实时查看日志内容(登陆、查询、退出),使用start启动不会又实时日志,不占用终端

[root@mycat ~]# ss -anplt |grep java

MySQL中间件之MyCat
###mycat端口8806

测试,查看数据是否同步:

[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> show databases;

MySQL中间件之MyCat

mysql> use TESTDB
mysql> show tables;

MySQL中间件之MyCat

mysql> select * from tab1;

MySQL中间件之MyCat

3、MyCat读写分离

Mycat的读写分离是创建在Mysql的主从复制的基础上的

修改配置文件 schema.xml

[root@mycat ~]# cd mycat/
[root@mycat mycat]# vim conf/schema.xml

一、设置balance="1"与writeType="0"

Balance参数设置:
    修改的balance属性,经过此属性配置读写分离的类型负载均衡类型,目前的取值有4 种: 
   balance="0",不开启读写分离机制, 全部读操做都发送到当前可用的 writeHost 上。 
   balance="1",所有的 readHost与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1, M2->S2,而且M1与M2 互为主备),正常状况下, M2,S1,S2 都参与 select 语句的负载均衡。
   balance="2",全部读操做都随机的在 writeHost、 readhost 上分发。
   balance="3",全部读请求随机的分发到 readhost 执行,writerHost 不负担读压力
WriteType参数设置:
   writeType=“0”, 全部写操做都发送到可用的writeHost上。
   writeType=“1”,全部写操做都随机的发送到readHost。
   writeType=“2”,全部写操做都随机的在writeHost、readhost分上发。

“readHost是从属于writeHost的,即意味着它从那个writeHost获取同步数据,所以,当它所属的writeHost宕机了,则它也不会再参与到读写分离中来,即“不工做了”,这是由于此时,它的数据已经“不可靠”了。基于这个考虑,目前mycat 1.3和1.4版本中,若想支持MySQL一主一从的标准配置,而且在主节点宕机的状况下,从节点还能读取数据,则须要在Mycat里配置为两个writeHost并设置banlance=1。”

二、设置switchType="2" 与slaveThreshold="100"

switchType 目前有三种选择:
   -1:表示不自动切换
   1 :默认值,自动切换
   2 :基于MySQL主从同步的状态决定是否切换

“Mycat心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性: switchType="2" 与slaveThreshold="100",此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制。Mycat心跳机制经过检测 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三个字段来
肯定当前主从同步的状态以及Seconds_Behind_Master主从复制时延。

三、修改配置文件,启动程序

[root@mycat mycat]# vim conf/schema.xml

MySQL中间件之MyCat

①控制台启动:mycat/bin 目录下执行 ./mycat console
②后台启动:mycat/bin 目录下./mycat start
为了能第一时间看到启动日志,方便定位问题,选择①控制台启动。

[root@mycat mycat]# ./bin/mycat console

登陆后台管理窗口 此登陆方式用于管理维护 Mycat

[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066

四、验证读写分离 my.cnf binlog_format=STATEMENT

(1) 在写主机插入数据:

[root@mysql02 ~]# mysql -uroot -p123.com
mysql> use test1;
mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.01 sec)

mysql> insert into tab1 values(4);
Query OK, 1 row affected (0.02 sec)

mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
4 rows in set (0.00 sec)

主从主机数据不一致了

[root@mysql01 ~]# mysql -uroot -p123.com
mysql> use test1
mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

(2) 在Mycat里查询:

mysql> use TESTDB
mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
4 rows in set (0.00 sec)

4、垂直拆分--分库

一个数据库由不少表的构成,每一个表对应着不一样的业务,垂直切分是指按照业务将表进行分类, 分布到不一样 的数据库上面,这样也就将数据或者说压力分担到不一样的库
如何划分表分库的原则:有紧密关联关系的表应该在一个库里,相互没有关联关系的表能够分到不一样的库里。

这个案例中须要一台新的mysql来进行分库操做。

主机 操做系统 IP地址
mysql01(master01) CentOS 7.3 192.168.1.1
mysql02(slave) CentOS 7.3 192.168.1.8
mycat CentOS 7.3 192.168.1.3
mysql03(master02) CentOS 7.3 192.168.1.9

先将上一个案例插入的数据删除

[root@mysql02 ~]# mysql -uroot -p123.com
mysql> delete from tab1 where id=4;
Query OK, 1 row affected (0.01 sec)

mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> use TESTDB

mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

以下四个表:
客户表分在一个数据库,另外三张都须要关联查询,分在另一个数据库。

#客户表 rows:20万
CREATE TABLE customer(
id INT AUTO_INCREMENT,
NAME VARCHAR(200),
PRIMARY KEY(id)
);
#订单表 rows:600万
CREATE TABLE orders(
id INT AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id)
);
#订单详细表 rows:600万
CREATE TABLE orders_detail(
id INT AUTO_INCREMENT,
detail VARCHAR(2000),
order_id INT,
PRIMARY KEY(id)
);
#订单状态字典表 rows:20
CREATE TABLE dict_order_type(
id INT AUTO_INCREMENT,
order_type VARCHAR(200),
PRIMARY KEY(id)
);

实现分库:

一、 修改 schema 配置文件

[root@mycat mycat]# vim conf/schema.xml

MySQL中间件之MyCat

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
                <table name="customer" dataNode="dn2"> </table>
        </schema> 
        <dataNode name="dn1" dataHost="host1" database="test1" />
        <dataNode name="dn2" dataHost="host2" database="test1" />
        <dataHost name="host1" maxCon="1000" minCon="10" balance="1"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="192.168.1.1:3306" user="root"
                                   password="123.com">
                        <readHost host="hostS2" url="192.168.1.8:3306" user="root" password="123.com" />
                </writeHost>
        </dataHost> 
        <dataHost name="host2" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM2" url="192.168.1.9:3306" user="root"
                                   password="123.com">
                </writeHost> 
        </dataHost>

</mycat:schema>

受权MyCat远程登录mysql03

[root@mysql03 ~]# mysql -uroot -p123.com
mysql> grant all on *.* to root@'192.168.1.%' identified by '123.com';

由于在配置文件中逻辑库所对应的真实库mysql03中并无,须要在mysql03中建立

mysql> create database test1;

二、 重启mycat,访问MyCat,建立表

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066

mysql> use TESTDB
mysql> CREATE TABLE customer(
    -> id INT AUTO_INCREMENT,
    -> NAME VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE orders(
    -> id INT AUTO_INCREMENT,
    -> order_type INT,
    -> customer_id INT,
    -> amount DECIMAL(10,2),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE orders_detail(
    -> id INT AUTO_INCREMENT,
    -> detail VARCHAR(2000),
    -> order_id INT,
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE dict_order_type(
    -> id INT AUTO_INCREMENT,
    -> order_type VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
+-----------------     +
| Tables_in_test1 |
+-----------------     +
| customer           |
| dict_order_type |
| orders               |
| orders_detail    |
| tab1                  |
+-----------------    +
5 rows in set (0.05 sec)

使用mysql01查看表:

mysql> show tables;
+-----------------    +
| Tables_in_test1 |
+-----------------    +
| dict_order_type |
| orders               |
| orders_detail    |
| tab1                  |
+-----------------    +
4 rows in set (0.00 sec)

使用mysql03查看表:

mysql> use test1;
mysql> show tables;
+-----------------     +
| Tables_in_test1 |
+-----------------     +
| customer           |
+-----------------     +
1 row in set (0.00 sec)

查看结构

mysql> desc customer;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id          | int(11)           | NO    | PRI | NULL    | auto_increment |
| NAME  | varchar(200) | YES  |     | NULL       |                |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

5、水平拆分--分表

相对于垂直拆分,水平拆分不是将表作分类,而是按照某个字段的某种规则来分散到多个库之中, 每一个表中 包含一部分数据。简单来讲,咱们能够将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其余的数据库中。
实现分表 选择要拆分的表 MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会影响查询效率,须要进行水平拆分(分表)进行优化。 例如:上一案例的 orders、orders_detail 都已经达到600 万行数据,须要进行分表优化。 分表字段以 orders 表为例,能够根据不一样自字段进行分表

编号 分表字段 效果
1 id(主键、或建立时间) 查询订单注重时效,历史订单被查询的次数少,如此分片会形成一个节点访问多,一个访问少,不平均。
2 customer_id(客户ID) 根据客户 id 去分,两个节点访问平均,一个客户的全部订单都在同一个节点

一、修改配置文件 schema.xml

[root@mycat mycat]# vim conf/schema.xml

MySQL中间件之MyCat

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
                <table name="customer" dataNode="dn2"> </table>
                <table name="orders" dataNode="dn1,dn2" rule="mod_rule">
                        <childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
                </table>
        </schema> 
        <dataNode name="dn1" dataHost="host1" database="test1" />
        <dataNode name="dn2" dataHost="host2" database="test1" />
        <dataHost name="host1" maxCon="1000" minCon="10" balance="1"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="192.168.1.1:3306" user="root"
                                   password="123.com">
                        <readHost host="hostS2" url="192.168.1.8:3306" user="root" password="123.com" />
                </writeHost>
        </dataHost> 
        <dataHost name="host2" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM2" url="192.168.1.9:3306" user="root"
                                   password="123.com">
                </writeHost> 
        </dataHost>

二、修改配置文件rule.xml

[root@mycat mycat]# vim conf/rule.xml

#在 rule 配置文件里新增分片规则 mod_rule,并指定规则适用字段为 customer_id,
#还有选择分片算法 mod-long(对字段求模运算) , customer_id 对两个节点求模,根据结果分片

38         <tableRule name="mod_rule">
 39                 <rule>
 40                         <columns>customer_id</columns>
 41                         <algorithm>mod-long</algorithm>
 42                 </rule>
 43         </tableRule>
 ……
 105         <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
 106                 <!-- how many data nodes -->
 107                 <property name="count">2</property>
#配置算法 mod-long 参数 count 为 2,两个节点
 108         </function>

三、由于在dn2(mysql03:192.168.1.9)上并无orders表,在数据节点dn2上建立orders表,并重启mycat服务

[root@mysql03 ~]# mysql -uroot -p123.com
mysql> use test1;
mysql> CREATE TABLE orders(
    -> id INT AUTO_INCREMENT,
    -> order_type INT,
    -> customer_id INT,
    -> amount DECIMAL(10,2),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.00 sec)

四、在MyCat中向orders表插入数据,insert字段不能省略

[root@mycat mycat]# mysql -umycat -p123456 -P8066 -h192.168.1.3
mysql> use TESTDB

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES (1,101,100,100100);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(2,101,100,100300);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(3,101,101,120000);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(4,101,101,103000);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(5,102,101,100400);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(6,102,100,100020);
Query OK, 1 row affected (0.01 sec)

#在mycat、dn一、dn2中查看orders表数据,分表成功
MySQL中间件之MyCat

dn1(mysql01:192.168.1.1):

[root@mysql01 ~]# mysql -uroot -p123.com
mysql> use test1;
mysql> select * from orders;
+----+------------+-------------+-----------+
| id | order_type | customer_id | amount    |
+----+------------+-------------+-----------+
|  2 |        101 |         100 | 100300.00 |
|  4 |        101 |         101 | 103000.00 |
|  6 |        102 |         100 | 100020.00 |
+----+------------+-------------+-----------+
3 rows in set (0.00 sec)

dn2(mysql03:192.168.1.9):

[root@mysql03 ~]# mysql -uroot -p123.com
mysql> use test1;

mysql> select * from orders;
+----+------------+-------------+-----------+
| id | order_type | customer_id | amount    |
+----+------------+-------------+-----------+
|  1 |        101 |         100 | 100100.00 |
|  3 |        101 |         101 | 120000.00 |
|  5 |        102 |         101 | 100400.00 |
+----+------------+-------------+-----------+
3 rows in set (0.00 sec)

在dn2(mysql03:192.168.1.9) 建立 orders_detail 表

mysql> CREATE TABLE orders_detail(
    -> id INT AUTO_INCREMENT,
    -> detail VARCHAR(2000),
    -> order_id INT,
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.02 sec)

重启 Mycat 访问 Mycat 向 orders_detail 表插入数据

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> use TESTDB
mysql> insert into orders_detail(id,detail,order_id) values (1,'detail',1);
Query OK, 1 row affected (0.03 sec)

mysql> insert into orders_detail(id,detail,order_id) values (2,'detail',2);
Query OK, 1 row affected (0.00 sec)

mysql> insert into orders_detail(id,detail,order_id) values (3,'detail',3);
Query OK, 1 row affected (0.01 sec)

mysql> insert into orders_detail(id,detail,order_id) values (4,'detail',4);
Query OK, 1 row affected (0.01 sec)

mysql> insert into orders_detail(id,detail,order_id) values (5,'detail',5);
Query OK, 1 row affected (0.00 sec)

mysql> insert into orders_detail(id,detail,order_id) values (6,'detail',6);
Query OK, 1 row affected (0.01 sec)

mysql> select o.*,od.detail from orders as o inner join orders_detail as od on o.id=od.order_id;
+----+------------+-------------+-----------+--------+
| id | order_type | customer_id | amount    | detail |
+----+------------+-------------+-----------+--------+
|  1 |        101 |         100 | 100100.00 | detail |
|  3 |        101 |         101 | 120000.00 | detail |
|  5 |        102 |         101 | 100400.00 | detail |
|  2 |        101 |         100 | 100300.00 | detail |
|  4 |        101 |         101 | 103000.00 | detail |
|  6 |        102 |         100 | 100020.00 | detail |
+----+------------+-------------+-----------+--------+
6 rows in set (0.03 sec)

使用dn一、dn2查看:

mysql> select * from orders_detail;

MySQL中间件之MyCat

mysql> select * from orders_detail;

MySQL中间件之MyCat

6、全局表

在分片的状况下,当业务表由于规模而进行分片之后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,考虑到字典表具备如下几个特性:

变更不频繁 
数据量整体变化不大 
数据规模不大,不多有超过数十万条记录

鉴于此, Mycat 定义了一种特殊的表,称之为“全局表”,全局表具备如下特性:

全局表的插入、更新操做会实时在全部节点上执行,保持各个分片的数据一致性
全局表的查询操做,只从一个节点获取 
全局表能够跟任何一个表进行 JOIN 操做 将字典表或者符合字典表特性的一些表定义为全局表,则从另一个方面,很好的解决了数据 JOIN 的难题。

经过全局表+基于 E-R 关系的分片策略, Mycat 能够知足 80%以上的企业应用开发

[root@mycat mycat]# vim conf/schema.xml

MySQL中间件之MyCat

<table name="dict_order_type" dataNode="dn1,dn2" type="global"> </table>

在dn2(mysql03:192.168.1.9)建立dict_order_type表

mysql> CREATE TABLE dict_order_type(
    -> id INT AUTO_INCREMENT,
    -> order_type VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

重启MyCat,访问MyCat向dict_order_type表插入数据

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> use TESTDB

mysql>  insert into dict_order_type (id,order_type) values (101,'type1');
Query OK, 1 row affected (0.03 sec)

mysql>  insert into dict_order_type (id,order_type) values (102,'type2');
Query OK, 1 row affected (0.01 sec)

mysql> select * from dict_order_type;
+-----+------------+
| id  | order_type |
+-----+------------+
| 101 | type1      |
| 102 | type2      |
+-----+------------+
2 rows in set (0.03 sec)

经常使用分片规则

取模:此规则为对分片字段求摸运算。 也是水平分表最经常使用规则。 5.1 配置分表中, orders 表采用了此规则。 分片枚举:经过在配置文件中配置可能的枚举 id,本身配置分片,本规则适用于特定的场景,好比有些业务 须要按照省份或区县来作保存,而全国省份区县固定的,这类业务使用本条规则。