转载请注明出处:http://blog.csdn.net/l1028386804/article/details/77150670

一、简单描述

取模分片,就是根据数据表的某一个字段,通常是某一个整数型的字段,对其进行十进制的求模运算,将运算结果作为Mycat的路由结果,具体规则如下:

此分片算法根据id进行十进制求模运算,相比固定的分片hash,这种分片算法在批量插入时会增加事务一致性的难度。

二、实现取模分片

1、配置rule.xml

在rule.xml中添加如下配置

<tableRule name="mod-long"><rule><columns>id</columns><algorithm>mod-long</algorithm></rule>
</tableRule>
<function name="mod-long" class="org.opencloudb.route.function.PartitionByMod"><!-- how many data nodes --><property name="count">3</property>
</function>

2、配置schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/" ><schema name="lyzdb" checkSQLschema="false" sqlMaxLimit="100"><!-- global table is auto cloned to all defined data nodes ,so can join with any table whose sharding node is in the same data node --><table name="t_user" primaryKey="id" dataNode="dn1,dn2,dn3" rule="mod-long"/></schema><!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743" /> --><dataNode name="dn1" dataHost="localhost1" database="db1" /><dataNode name="dn2" dataHost="localhost1" database="db2" /><dataNode name="dn3" dataHost="localhost1" database="db3" /><!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" /><dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" /> <dataNode name="jdbc_dn2" dataHost="jdbchost" database="db2" /> <dataNode name="jdbc_dn3"   dataHost="jdbchost" database="db3" /> --><dataHost name="localhost1" 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.209.137:3306" user="root" password="root"></writeHost><!--<writeHost host="hostS1" url="localhost:3316" user="root"--><!--password="123456" />--><!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --></dataHost>
</mycat:schema>

至此,Mycat的配置工作就算完成了,下面,我们一起来测试下Mycat的路由结果。

三、测试路由结果

1、创建数据表

mysql> explain CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME);
+-----------+------------------------------------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                                                    |
+-----------+------------------------------------------------------------------------------------------------------------------------+
| dn1       | CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME) |
| dn2       | CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME) |
| dn3       | CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME) |
+-----------+------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)mysql> CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME);
Query OK, 0 rows affected (0.21 sec)

Mycat日志如下:

08/13 21:44:36.871  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME), route={1 -> dn1{CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME)}2 -> dn2{CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME)}3 -> dn3{CREATE TABLE t_user (ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(64),sex VARCHAR(2), CREATE_TIME DATETIME)}
} rrs

由此可见,当创建数据表时,Mycat将SQL路由到所有的数据节点。

2、录入数据

mysql> explain insert into t_user(id,name, sex, CREATE_TIME) values(1,'lyz01', 'n', NOW());
+-----------+-----------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                         |
+-----------+-----------------------------------------------------------------------------+
| dn2       | insert into t_user(id,name, sex, CREATE_TIME) values(1,'lyz01', 'n', NOW()) |
+-----------+-----------------------------------------------------------------------------+
1 row in set (0.00 sec)mysql>
mysql>
mysql> insert into t_user(id,name, sex, CREATE_TIME) values(1,'lyz01', 'n', NOW());
Query OK, 1 row affected (0.10 sec)mysql> explain insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW());
+-----------+-----------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                         |
+-----------+-----------------------------------------------------------------------------+
| dn3       | insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW()) |
+-----------+-----------------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW());
Query OK, 1 row affected (0.04 sec)mysql> explain insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW());
+-----------+-----------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                         |
+-----------+-----------------------------------------------------------------------------+
| dn1       | insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW()) |
+-----------+-----------------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW());
Query OK, 1 row affected (0.01 sec)

Mycat日志如下:

08/13 21:51:45.221  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]insert into t_user(id,name, sex, CREATE_TIME) values(1,'lyz01', 'n', NOW()), route={1 -> dn2{insert into t_user(id,name, sex, CREATE_TIME) values(1,'lyz01', 'n', NOW())}
} rrs insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW());
08/13 21:52:53.005  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW()), route={1 -> dn3{insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW())}
} rrs insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW());
08/13 21:54:00.546  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW()), route={1 -> dn1{insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW())}
} rrs

由此可见,录入数据时,Mycat根据id进行十进制求模运算,将运算结果作为路由结果,将SQL路由到指定的数据分片节点,符合我们配置的分片规则。

3、指定数据分片字段查询

08/13 21:51:45.221  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]insert into t_user(id,name, sex, CREATE_TIME) values(1,'lyz01', 'n', NOW()), route={1 -> dn2{insert into t_user(id,name, sex, CREATE_TIME) values(1,'lyz01', 'n', NOW())}
} rrs insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW());
08/13 21:52:53.005  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW()), route={1 -> dn3{insert into t_user(id,name, sex, CREATE_TIME) values(2,'lyz02', 'n', NOW())}
} rrs insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW());
08/13 21:54:00.546  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW()), route={1 -> dn1{insert into t_user(id,name, sex, CREATE_TIME) values(3,'lyz03', 'n', NOW())}
} rrs

Mycat日志如下:

08/13 21:55:57.257  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]select * from t_user where id = 1, route={1 -> dn2{select * from t_user where id = 1}
} rr

由此可见,执行简单的查询,如果指定分片字段,则走分片查询单个分片节点。

4、按照分片字段范围查询

mysql> explain select * from t_user where id >=3;
+-----------+----------------------------------------------+
| DATA_NODE | SQL                                          |
+-----------+----------------------------------------------+
| dn1       | SELECT * FROM t_user WHERE id >= 3 LIMIT 100 |
| dn2       | SELECT * FROM t_user WHERE id >= 3 LIMIT 100 |
| dn3       | SELECT * FROM t_user WHERE id >= 3 LIMIT 100 |
+-----------+----------------------------------------------+
3 rows in set (0.02 sec)mysql> select * from t_user where id >=3;
+----+-------+------+---------------------+
| ID | name  | sex  | CREATE_TIME         |
+----+-------+------+---------------------+
|  3 | lyz03 | n    | 2017-08-13 21:54:00 |
+----+-------+------+---------------------+
1 row in set (0.04 sec)

Mycat日志如下:

08/13 21:58:08.598  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]select * from t_user where id >=3, route={1 -> dn1{SELECT *
FROM t_user
WHERE id >= 3
LIMIT 100}2 -> dn2{SELECT *
FROM t_user
WHERE id >= 3
LIMIT 100}3 -> dn3{SELECT *
FROM t_user
WHERE id >= 3
LIMIT 100}
} rrs 

由此可见,如果分片字段范围的查询,则走所有节点去检索,哪怕只有一条数据在一个分片上,route路由也是走所有的分片进行检索查询。

5、按照非分片字段查询

mysql> explain select * from t_user where name = 'lyz01';
+-----------+-----------------------------------------------------+
| DATA_NODE | SQL                                                 |
+-----------+-----------------------------------------------------+
| dn1       | SELECT * FROM t_user WHERE name = 'lyz01' LIMIT 100 |
| dn2       | SELECT * FROM t_user WHERE name = 'lyz01' LIMIT 100 |
| dn3       | SELECT * FROM t_user WHERE name = 'lyz01' LIMIT 100 |
+-----------+-----------------------------------------------------+
3 rows in set (0.00 sec)mysql>
mysql> select * from t_user where name = 'lyz01';
+----+-------+------+---------------------+
| ID | name  | sex  | CREATE_TIME         |
+----+-------+------+---------------------+
|  1 | lyz01 | n    | 2017-08-13 21:51:45 |
+----+-------+------+---------------------+
1 row in set (0.01 sec)

Mycat日志如下:

08/13 21:59:01.166  DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=lyzdb, host=192.168.209.1, user=lyz,txIsolation=3, autocommit=true, schema=lyzdb]select * from t_user where name = 'lyz01', route={1 -> dn1{SELECT *
FROM t_user
WHERE name = 'lyz01'
LIMIT 100}2 -> dn2{SELECT *
FROM t_user
WHERE name = 'lyz01'
LIMIT 100}3 -> dn3{SELECT *
FROM t_user
WHERE name = 'lyz01'
LIMIT 100}
} rrs 

由此可见,如果不走分片字段的查询,即使是单个数据,也要route路由所有的分片,走所有的分片进行查询。

Mycat之——取模分片相关推荐

  1. mycat分表之ER表分片、范围分片、取模分片、日期分片、全局表等

    概述 数据库进行水平分表时,需要按照一定规则对数据进行分片. Mycat的分片策略可以分为两种: 连续分片和离散分片. 连续分片常用的有分片规则有: 范围分片. 日期分片. 优点:如果进行范围查询,比 ...

  2. mysql 数字取模_Mycat之数据库分片(取模分片)-yellowcong

    取模分片,简单来讲,根据数据库的主键和存储的节点数进行取模操作,然后根据取模的结果,将数据存放到对应的节点中,取模分表,可以将数据均匀的分配到各个库中.实现的步骤:1.创建数据库,2.配置schema ...

  3. Mycat范围求模分片

    讲解Myat范围求模分片规则之前,让我们先看如下这样的一个系统的特征: 比如一个系统,具备如下特点: 门店数量增长快,各集团内门店数量分布不均匀. 业务为统计类业务,都是基于某一段时间内,然后对某一集 ...

  4. Mycat分库分表分片方式

    1. 取模分片 <tableRule name="mod-long"><rule><columns>id</columns>< ...

  5. mysql分库分表取模扩容_MyCat分库分表策略——范围取模

    范围取模分片的优点在于,既拥有范围分片的固定范围数据不做迁移的优点,也拥有了取模分片对于热点数据均匀分布的优点.首先我们还是以一个示例进行讲解: id rang-mod 0 files/partiti ...

  6. Redis数据分布哈希后取模

    哈希后取模 例如,hash(key)%N,根据余数,决定映射到那一个节点.这种方式比较简单,属于静态的分片规则.但是一旦节点数量变化,新增或者减少,由于取模的N 发生变化,数据需要重新分布. 为了解决 ...

  7. 分区取模分库分表策略:多表事务分库内闭环解决方案

    简介: 当表数据超过一定量级,就需要通过分表来解决单表的性能瓶颈问题:当数据库负载超过一定水平线,就需要通过分库来解决单库的连接数.性能负载的瓶颈问题.本文将阐述在不同情况下,让不同数量级表,在同一个 ...

  8. Codeforces Round #104 (Div. 2) E DP(01背包模型) +组和+除法取模求逆元

    题意: 规定只包含4或7的数为幸运数字,给定n个数的序列,求他的子序列,使得该子序列的长度为k并且满足该子序列中不存在相同的两个幸运数字.问一共寻在多少种可能.(只要该数的下标不同则认为是不同的序列) ...

  9. python 除法取模_Python的运算符和表达式(上)

    上一篇文章霖小白分享了Python中的字符串和数字类型,这一篇让我们回到小学时代的数学,因为霖小白这一篇分享的是关于Python程序中的运算符和表达式,这一次先分享算术运算符和算术表达式,比较运算符和 ...

最新文章

  1. warning LNK4098: 默认库“MSVCRT”与其他库的使用冲突;使用 /NODEFAULTLIB:library问题解决方法
  2. 调试笔记--keil 测量周期小技巧
  3. ribbon负载均衡@LoadBalanced
  4. POJ 1932 XYZZY (差分约束+传递闭包)
  5. 正确判断js数据类型 总结记录
  6. WEB运用程序如何实现高效可维护?
  7. 经典面试题(36):以下代码将输出的结果是什么?
  8. JEECG寒假集训班开始报名啦!
  9. android 微信摇一摇动画效果
  10. 为SQL Server创建基于“智能”触发器的审核跟踪
  11. 中国脚手架管市场趋势报告、技术动态创新及市场预测
  12. RocketMQ3.2.6安装部署及调用
  13. Entity Framework - 利用T4 分离 Entity 和 DbContext
  14. event.srcElement 说明 方法 技巧
  15. 阶段5 3.微服务项目【学成在线】_day01 搭建环境 CMS服务端开发_03-项目概述-技术架构...
  16. 读取xml文件分析 EntityName 时出错的解决方案
  17. ogg格式怎样才能转换成MP3格式
  18. mpa和pis_有关压力单位pis-bar-mpa的换算
  19. numpy.take()用法总结
  20. 1.17英文题面翻译

热门文章

  1. kali linux有道卸载,有道云笔记如何卸载?彻底卸载有道云笔记教程
  2. 32位浮点数规格化 计算
  3. Python工具箱系列(十八)
  4. 超级无敌之python代码
  5. 统计学④——置信区间怎么算
  6. 【Word】如何在第N页开始页码/如何在word中使用两组不同页码?
  7. 4.PHP接入支付宝手机网站支付、移动支付接口
  8. python更新织梦网站_织梦DEDECMS自动更新首页的办法
  9. 年底大标季来袭,这份投标秘籍给你助力!
  10. android属性动画 呼吸,【MIUI动效】Android:会呼吸的悬浮气泡