

MySQL中间件之MyCat-A little pay
source link: https://blog.51cto.com/14638500/2471517
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

MySQL中间件之MyCat
一、MyCat基础概念
1、什么是MyCat
一个彻底开源的,面向企业应用开发的大数据库集群
支持事务、ACID、可以替代MySQL的加强版数据库
一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品
2、为什么使用MyCat
如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求。这个时候NoSQL的出现暂时解决了这一危机。它通过降低数据的安全性,减少对事务的支持,减少对复杂查询的支持,来获取性能上的提升。但是,在有些场合NoSQL一些折衷是无法满足使用场景的(比如有些使用场景是绝对要有事务与安全指标的。这个时候NoSQL肯定是无法满足的)。所以还是需要使用关系性数据库。如何使用关系型数据库解决海量存储的问题呢?此时就需要做数据库集群,为了提高查询性能将一个数据库的数据分散到不同的数据库中存储,为应对此问题就出现了——MyCat
MyCat作用:
能满足数据库数据大量存储;提高了查询性能
读写分离
数据分片 垂直拆分(分库)、水平拆分(分表)、垂直+水平拆分(分库分表)
多数据源整合
3、 数据库中间件对比
① 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公司发布的中间件
4、支持的数据库
支持MySQL ORACLE SQLServer等一些主流的数据库
5、核心技术
分库分表:数据库分片指通过某种特定的条件,将我们存放在一个数据库中的数据分散存放在不同的多个数据库(主机)中,这样来达到分散单台设备的负载,根据切片规则,可分为以下两种切片模式,MyCAT通过定义表的分片规则来实现分片,每个表格可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法
1)Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。
2)Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。
3)DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上
4)DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上
5)分片规则:前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难
二、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,看上一个博客部署。
1、下载及安装,使用上面的官网地址下载。


复制链接,wget下载
[root@localhost ~]# wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

将压缩包解压缩。建议将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

###mycat端口8806
测试,查看数据是否同步:
[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> show databases;

mysql> use TESTDB
mysql> show tables;

mysql> select * from tab1;

三、MyCat读写分离
Mycat的读写分离是建立在Mysql的主从复制的基础上的
修改配置文件 schema.xml
[root@mycat ~]# cd mycat/
[root@mycat mycat]# vim conf/schema.xml
1、设置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。”
2、设置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主从复制时延。
3、修改配置文件,启动程序
[root@mycat mycat]# vim conf/schema.xml

①控制台启动: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
4、验证读写分离 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)
四、垂直拆分--分库
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类, 分布到不同 的数据库上面,这样也就将数据或者说压力分担到不同的库
如何划分表分库的原则:有紧密关联关系的表应该在一个库里,相互没有关联关系的表可以分到不同的库里。
这个案例中需要一台新的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)
);
实现分库:
1、 修改 schema 配置文件
[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">
<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;
2、 重启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)
五、水平拆分--分表
相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中, 每个表中 包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中。
实现分表 选择要拆分的表 MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会影响查询效率,需要进行水平拆分(分表)进行优化。 例如:上一案例的 orders、orders_detail 都已经达到600 万行数据,需要进行分表优化。 分表字段以 orders 表为例,可以根据不同自字段进行分表
编号 | 分表字段 | 效果 |
---|---|---|
1 | id(主键、或创建时间) | 查询订单注重时效,历史订单被查询的次数少,如此分片会造成一个节点访问多,一个访问少,不平均。 |
2 | customer_id(客户ID) | 根据客户 id 去分,两个节点访问平均,一个客户的所有订单都在同一个节点 |
1、修改配置文件 schema.xml
[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">
<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>
2、修改配置文件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>
3、因为在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)
4、在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、dn1、dn2中查看orders表数据,分表成功

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)
使用dn1、dn2查看:
mysql> select * from orders_detail;

mysql> select * from orders_detail;

六、全局表
在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,考虑到字典表具有以下几个特性:
变动不频繁
数据量总体变化不大
数据规模不大,很少有超过数十万条记录
鉴于此, Mycat 定义了一种特殊的表,称之为“全局表”,全局表具有以下特性:
全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性
全局表的查询操作,只从一个节点获取
全局表可以跟任何一个表进行 JOIN 操作 将字典表或者符合字典表特性的一些表定义为全局表,则从另外一个方面,很好的解决了数据 JOIN 的难题。
通过全局表+基于 E-R 关系的分片策略, Mycat 可以满足 80%以上的企业应用开发
[root@mycat mycat]# vim conf/schema.xml

<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,自己配置分片,本规则适用于特定的场景,比如有些业务 需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK