一、简介
上一篇文章介绍了如何在MyCat中实现取模范围分片,其实还有一个分片方式与它很相似,那就是本节讲解的ASCII码取模范围分片。
- 实现方式:与取模范围算法类似,支持数值、符号、字母取模。根据配置的分片字段,截取长度为 prefixLength 的子串,在对子串中每一个字符的 ASCII 码求和,然后对 各个字符的ASCII 码求和值进行取模运算(sum % patternValue),再跟分片范围进行匹配,就可以计算出子串的分片节点。
- 优点:可以自由决定每个数据所在分片。
- 缺点:需要我们提前规划好dataNode,扩展比较麻烦。
二、ASCII取模范围分片
实现步骤:
【a】创建数据库和表
use ascii01;
create table user(id bigint not null primary key,name varchar(20));use ascii02;
create table user(id bigint not null primary key,name varchar(20));
【b】配置server.xml: 逻辑库信息、用户信息
<user name="root"><property name="password">0905</property><property name="schemas">TESTASCII</property><!-- 表级 DML 权限设置 --><!-- <privileges check="false"><schema name="TESTDB" dml="0110" ><table name="tb01" dml="0000"></table><table name="tb02" dml="1111"></table></schema></privileges> -->
</user><user name="user"><property name="password">user</property><property name="schemas">TESTASCII</property><property name="readOnly">true</property>
</user>
【c】配置rule.xml,定义分片规则
<tableRule name="partition-by-ascii"><rule><columns>id</columns><algorithm>sharding-by-pattern-ascii</algorithm></rule>
</tableRule><function name="sharding-by-pattern-ascii" class="io.mycat.route.function.PartitionByPrefixPattern"><property name="mapFile">partition-pattern-ascii.txt</property><property name="patternValue">256</property><property name="prefixLength">5</property>
</function>
【d】配置partition-pattern-ascii.txt取模分片规则
- vim partition-pattern-ascii.txt
1-32=1
33-64=2
65-128=3
129-256=4
0-0=0
- 注意:在mapFile配置的文件中,其1-32 表示的为截取 id之后的子串每一个字符的ASCII码和 % 256后分布的范围。
【e】配置schema.xml,指定分片表,分片规则,分片节点等
<schema name="TESTASCII" checkSQLschema="true" sqlMaxLimit="1000"><table name="user" dataNode="dn$1-5" primaryKey="id" rule="partition-by-ascii" />
</schema><dataNode name="dn1" dataHost="dataHost01" database="ascii01" />
<dataNode name="dn2" dataHost="dataHost01" database="ascii02" />
<dataNode name="dn3" dataHost="dataHost01" database="ascii01" />
<dataNode name="dn4" dataHost="dataHost01" database="ascii02" />
<dataNode name="dn5" dataHost="dataHost01" database="ascii01" /><dataHost name="dataHost01" maxCon="1000" minCon="10" balance="0"writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"><heartbeat>select user()</heartbeat><writeHost host="hostM1" url="192.168.179.130:3306" user="root" password="0905" />
</dataHost>
【f】测试插入数据
重启mycat:
- cd /bin
- ./mycat restart
- mysql -uroot -p0905 -h192.168.179.130 -P8066
insert into user(id,name) values(1111111,'zhangsan');
insert into user(id,name) values(2222222,'lisi');
insert into user(id,name) values(3333333,'wangwu');
insert into user(id,name) values(4444444,'zhaoliu');
insert into user(id,name) values(8960000,'tianqi');
分析:
- 1111111截取前五位 是 11111, 11111每个字符的ascii码之和为:49 * 5 = 245
- 245 % 256 = 245 : 满足129-256=4,datanode index = 4,即在第五个节点dn5, 所以该条数据插入到ascii01库。
- 2222222截取前五位 是 22222:22222每个字符的ascii码之和为:50 * 5 = 250
- 250 % 256 = 250:满足129-256=4,datanode index = 4,即在第五个节点dn5 所以该条数据插入到ascii01库。
- 3333333截取前五位 是 33333:3333每个字符的ascii码之和为:51 * 5 = 255
- 255 % 256 = 255:满足129-256=4,datanode index = 4,即在第五个节点dn5 所以该条数据插入到ascii01库。
- 44444截取前五位 是 44444:44444每个字符的ascii码之和为:52 * 5 = 260
- 260 % 256 = 4:满足1-32=1,datanode index = 1,即在第二个节点dn2 所以该条数据插入到ascii02库。
- 8960000截取前五位 是 89600:89600每个字符的ascii码之和为:56 + 57 + 54 + 48 + 48 = 263
- 263 % 256 = 7:满足1-32=1,datanode index =1,即在第二个节点dn2 所以该条数据插入到ascii02库。