1 问题
- 取模
前边介绍了根据表中某一个字段进行取模运算后的余数,来对数据表的存储进行分片,这种分片对数据实现的分片,带有随机性;
- 枚举
也介绍了将表中的某一个字段,按照我们指定的存储节点,将其保存到我们期望的数据库节点中,这种分片对用户是透明的。但是,枚举的方式,一次仅能设置一条,假如数据量很大时,这将变得很难维护。
- 范围
于是,就有了范围约定的分片模式,我们可以对一个范围内的数据设置分片规则,从而解决了需要大量枚举列举带来的工作量。
2 实现原理
提前规划好数据表中某个字段,当其取值在某个范围内时,数据保存到哪个分片。
- 优点
明确知道哪些数据,会保存到哪个数据库分片中。
- 缺点
如果短时间内同属同一范围内的字段,有大批量插入操作时,保存该范围数据的分片将承担比较大的压力,而其他分片可能处于闲置状态,无法利用其他节点来分担压力。可能会引发热点数据问题。
3 实现过程
3.1 修改配置 schema.xml
在配置文件中schema标签下,新增加一条 table 内容,将数据表 payment_address 按照分片规则 partition_area ,将其分配到 dn1,dn2 两个数据库中。
<table name="payment_address" dataNode="dn1,dn2" rule="partition_area"></table>
修改后的配置文件片段如下
3.2 修改配置 rule.xml
3.2.1 tableRule 标签
在配置文件中新增一个 tableRule 标签
- name 分片规则名,与 schema.xml 文件中 table 标签的 rule 属性相同;
- cloumns 根据数据表中的指定列,计算分片规则;
- algorithm 具体的分片算法。
<tableRule name="partition_area">
<rule>
<columns>area_id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
3.2.2 function 标签
标签下各字段作用和枚举相似。
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
该分片调用的类如下:
3.2.3 mapFile 文件
打开 function 标签下 property 对应的规则文件。该文件与 rule.xml 在同一个目录下。
修改其中的内容为
100000-300000=0
300001-900000=1
需要注意的是:
这里配置的范围,不能出现交叉。
3.3 重启mycat
mycat restart
3.4 验证
3.4.1 创建数据表
进入mycat的数据端口,执行create语句。
create table payment_address(id int auto_increment primary key, area_id int, area_str varchar(50));
3.4.2 插入数据
向表中插入四条记录
insert into PAYMENT_ADDRESS(id, area_id, area_str) values(1, 300001, "yunnan");
insert into PAYMENT_ADDRESS(id, area_id, area_str) values(2, 270011, "sichuan");
insert into PAYMENT_ADDRESS(id, area_id, area_str) values(4, 300001, "yunnan");
insert into PAYMENT_ADDRESS(id, area_id, area_str) values(6, 700000, "heilongjiang");
3.4.3 查询数据
在mycat中查询
在dn1中查询
在dn2中查询