Mycat水平分表

第五章 水平拆分——分表

1.简单分表,针对单表单字段取模

相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中 包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就 是将表中的某些行切分 到一个数据库,而另外的某些行又切分到其他的数据库中,如图:
在这里插入图片描述

①创建表orders表在另外一个mysql服务器中

CREATE TABLE orders( 
id INT AUTO_INCREMENT, 
order_type INT, 
customer_id INT, 
amount DECIMAL(10,2), 
PRIMARY KEY(id) 
);

②设计分表策略

customer_id(客户 id)
根据客户 id 去分,两个节点访问平均,一个客户的所
有订单都在同一个节点

③修改schema.xml

新增:

#配置分表规则方法

④修改rule.xml

1.新增规则类
  <tableRule name="mod_rule">
                <rule>
                         <columns>customer_id</columns>  #通过顾客id分库
                         <algorithm>mod-long</algorithm>  #策略为取模
                 </rule>
      </tableRule>
2.新增规则方式
 <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
                <!-- how many data nodes -->
                <property name="count">2</property>  #表示取模2
 </function>

⑤重启mycat服务,登录mycat用户

⑥mycat插入语句测试

INSERT INTO orders(id,order_type,customer_id,amount) VALUES (1,101,100,100100); 
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(2,101,100,100300); 
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(3,101,101,120000); 
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(4,101,101,103000); 
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(5,102,101,100400); 
INSERT INTO orders(id,order_type,customer_id,amount) VALUES(6,102,100,100020); 

⑦测试效果

分别查看mysql服务器1和mysql服务器2,orders库中的orders表,确实是通过取模2来的

2.带上join分表实现原理

Orders 订单表已经进行分表操作了,和它关联的 orders_detail 订单详情表如何进行 join 查询。我们要对 orders_detail 也要进行分片操作。Join 的原理如下图:
在这里插入图片描述

1、 ER 表

Mycat 借鉴了 NewSQL 领域的新秀 Foundation DB 的设计思路,Foundation DB 创新性的提 出了 Table Group 的概念,其将子表的存储位置依赖于主表,并且物理上紧邻存放,因此彻底解决了 JION 的效率和性能问 题,根据这一思路,提出了基于 E-R 关系的数据分片策略,子表的记录与所 关联的父表记录存放在同一个数据分片上。

①另外一张dn2创建表
CREATE TABLE orders_detail( 
id INT AUTO_INCREMENT, 
detail VARCHAR(2000), 
order_id INT, 
PRIMARY KEY(id) 
); 
②修改配置文件schuma.xml
③访问 Mycat 向 orders_detail 表插入数据
INSERT INTO orders_detail(id,detail,order_id) values(1,'detail1',1); 
INSERT INTO orders_detail(id,detail,order_id) VALUES(2,'detail1',2); 
INSERT INTO orders_detail(id,detail,order_id) VALUES(3,'detail1',3); 
INSERT INTO orders_detail(id,detail,order_id) VALUES(4,'detail1',4); 
INSERT INTO orders_detail(id,detail,order_id) VALUES(5,'detail1',5); 
INSERT INTO orders_detail(id,detail,order_id) VALUES(6,'detail1',6); 
④测试,在mycat、dn1、dn2中运行两个表join语句对比一下
select o.*,od.detail from orders o inner join orders_detail od on o.id=od.order_id;

2.配置全局表

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

2.1修改schema.xml文件
2.2在dn2中创建字典表
#订单状态字典表 rows:20 
CREATE TABLE dict_order_type( 
id INT AUTO_INCREMENT, 
order_type VARCHAR(200), 
PRIMARY KEY(id) 
);
2.3启动mysql服务,重启mycat服务

①service mysql restart
②进入mycat/bin目录,./mycat restart

2.4启动mycat插入语句测试

INSERT INTO dict_order_type(id,order_type) VALUES(101,‘type1’);
INSERT INTO dict_order_type(id,order_type) VALUES(102,‘type2’);
全局表配置完成

3.常用的分片规则

1.取模方式(详情在分表处)
2.分片枚举

通过在配置文件中配置可能的枚举 id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则。

①修改schema.xml文件
②修改rule.xml

(1)修改对应规则分片字段

<tableRule name="sharding_by_intfile">
                <rule>
                        <columns>areacode</columns>  #分片字段
                        <algorithm>hash-int</algorithm> #分片函数
                </rule>
  </tableRule>

(2)修改对应分片规则hash-int

     <function name="hash-int"
                class="io.mycat.route.function.PartitionByFileMap">
                <property name="mapFile">partition-hash-int.txt</property>#文件名称
                <property name="type">1</property>#0int 1String
                <property name="defaultNode">0</property>
#defaultNode:默认节点:小于 0 表示不设置默认节点,大于等于 0 表示设置默认节点, 

#设置默认节点如果碰到不识别的枚举值,就让它路由到默认节点,如不设置不识别就报错

③修改partition-hash-int.txt文件

110=0
120=1

④重启mycat服务,重新进入mycat

(1)./mycat restart
(2)mysql -umycat -p -h192.168.119.131 -P8066

⑤使用mycat创建表
CREATE TABLE orders_ware_info 
( 
`id` INT AUTO_INCREMENT comment '编号', 
`order_id` INT comment '订单编号', 
`address` VARCHAR(200) comment '地址', 
`areacode` VARCHAR(20) comment '区域编号', 
PRIMARY KEY(id) 
); 
⑥插入语句
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (1,1,'北京','110'); 
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (2,2,'天津','120'); 
⑦测试dn1,dn2测试是否成功通过内容分片了

select * from orders_ware_info

3.范围约定

①修改schema.xml
 >  <table name="payment_info" dataNode="dn1,dn2" rule="auto_sharding_long" ></table>
②修改rule.xml
     <tableRule name="auto_sharding_long">
                 <rule>
                        <columns>order_id</columns>     #分片字段
                         <algorithm>rang-long</algorithm>  #分片策略
                 </rule>
         </tableRule>


  <function name="rang-long"
                class="io.mycat.route.function.AutoPartitionByLong">
                <property name="mapFile">autopartition-long.txt</property>
                <property name="defaultNode">0</property>
  </function>

#mapFilie 标识配置文件名称
#defaultNode 默认节点小于0表示不设置默认节点,大于等于0表示设置默认节点
设置默认节点如果喷到不识别的枚举值,就让它路由到默认节点,如不设置不识别就报错

③修改autopartition-long.xml

0-102=0
103-200=1

④验证数据

1.启动mycat,并执行创建表
支付信息表
CREATE TABLE payment_info
(
id INT AUTO_INCREMENT comment ‘编号’,
order_id INT comment ‘订单编号’,
payment_status INT comment ‘支付状态’,
PRIMARY KEY(id)
);
2.插入数据

INSERT INTO payment_info (id,order_id,payment_status) VALUES (1,101,0);
INSERT INTO payment_info (id,order_id,payment_status) VALUES (2,102,1);
INSERT INTO payment_info (id,order_id ,payment_status) VALUES (3,103,0);
INSERT INTO payment_info (id,order_id,payment_status) VALUES (4,104,1);

3验证结果,查看两张表看看是否根据范围进行分表的
select * from payment_info;

4.时间分片
①修改schema.xml


②修改rule.xml


login_date
shardingByDate

<function name="shardingByDate" class="io.mycat.route.function.PartitionByDate">
             <property name="dateFormat">yyyy-MM-dd</property>
             <property name="sBeginDate">2019-01-01</property>
             <property name="sEndDate">2019-01-04</property>
            <property name="sPartionDay">2</property>
     </function>

columns:分片字段,algorithm:分片函数

#dateFormat :日期格式
#sBeginDate :开始日期
#sEndDate:结束日期,则代表数据达到了这个日期的分片后循环从开始分片插入
#sPartionDay :分区天数,即默认从开始日期算起,分隔 2 天一个分区
③验证数据
1.#创建用户信息表
CREATE TABLE login_info
(
id INT AUTO_INCREMENT comment ‘编号’,
user_id INT comment ‘用户编号’,
login_date date comment ‘登录日期’,
PRIMARY KEY(id)
);
2.#插入数据
INSERT INTO login_info(id,user_id,login_date) VALUES (1,101,‘2019-01-01’);
INSERT INTO login_info(id,user_id,login_date) VALUES (2,102,‘2019-01-02’);
INSERT INTO login_info(id,user_id,login_date) VALUES (3,103,‘2019-01-03’);
INSERT INTO login_info(id,user_id,login_date) VALUES (4,104,‘2019-01-04’);
INSERT INTO login_info(id,user_id,login_date) VALUES (5,103,‘2019-01-05’);
INSERT INTO login_info(id,user_id,login_date) VALUES (6,104,‘2019-01-06’);
3.#查dn1,dn2数据
select * from login_info;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z J X

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值