1 实现原理
有些业务需要按照一定规则来存放数据,这个分片规则需要由我们自己来定义。如我们在某东下单后,系统会根据收货地址,调用对应的区域仓库,安排发货。这类业务,就可以采用本条规则来实现。
2 实现过程
2.1 修改 schema.xml 文件
在schema.xml文件中,增加用于分片枚举的表及其配置信息
<table name="order_locations" dataNode="dn1,dn2" rule="partition_enum"></table>
将数据表 order_locations 采用规则名为 partition_enum 的方法进行分片,该规则将在 rule.xml 文件中进行配置。
2.2 修改 rule.xml 文件
2.2.1 tableRule标签
- name 规则名,与 schema.xml 文件中一致
- columns 用于分片的列名,该列应在数据表中的存在
- algorithm 实现分片规则的算法名,该名称应存在于 function 标签中
<tableRule name="partition_enum">
<rule>
<columns>area_code</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
2.2.2 function标签
算法名 hash-int 在原 rule.xml 文件中已经存在。
- name 算法的方法名
- class 可以看到该算法的具体实现类,
- property 该算法需要读取文件 partition-hash-int.txt 中的内容。
<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
</function>
可以在 gitee 上查看mycat的具体源码实现
在初始化时,读取了mapfile文件中的内容,并将其转换为 map
2.2.3 mapFile 属性
mapFile 文件保存位置和 rule.xml 文件在同一目录下。
打开文件后,可以看到里边的内容
等号前边,是需要进行分片的字段值;
等号后边,是数据存储的节点位置,0即dn1, 1即dn2。
具体为判断 area_code 的数值,
如果是 10000、10020 时,保存到dn1的分片数据库中;
如果是 10010、10030 时,保存到dn2的分片数据库中。
2.3 重新启动mycat
mycat restart
2.4 创建表
创建用于保存订单区域的数据表。
进入到Mycat数据端口,输入如下建表语句
mysql> create table order_locations(id int auto_increment primary key, order_id int, address varchar(100), area_code varchar(50));
2.5 插入数据并查询
在mycat数据端口,插入四条数据
insert into ORDER_LOCATIONS(id, order_id, address, area_code) values(1, 101, "shanghai waigaoqiao", "10000");
insert into ORDER_LOCATIONS(id, order_id, address, area_code) values(2, 102, "beijing xizhimen", "10010");
insert into ORDER_LOCATIONS(id, order_id, address, area_code) values(3, 103, "chongqing chaotianmen", "10020");
insert into ORDER_LOCATIONS(id, order_id, address, area_code) values(4, 104, "chengdu wuhouci", "10030");
在mycat中查询
在dn1中查询
在dn2中查询
数据保存的位置,和我们制定的分片规则完全一致。
3 注意
需要注意的是,我们在自定义分片的枚举规则时,mapFile 中应当列举出所有 area_code 中出现的数据,如果没有在 mapFile 中列出,在进行数据插入时将会报错,如下