一.背景:
Mycat 作为一个中间件,当不知道路由到哪个节点的时候,很多 SQL 语句就无法支持,比如存储过程,DDL语句、跨库查询语句。此时MyCat的注解就可以帮助我们实现这些功能。注解的作用就是帮助我们找到目标节点,然后让 Mycat 做一层透明的代理转发
二.用法
/*!mycat: sql=注解 SQL 语句*/ 真正执行的 SQL
原始 SQL | 注解 SQL |
特定分片 (不遵循分片规则) sele/ctdelete/insert/update | 比如/*!mycat: sql=select * from users where user_id=1*/select * from student(通过注解里的SQL能确定哪个分片即可) |
DDL | /*!mycat: sql=select * from customer where id =1 */ CREATE TABLE test2(id INT); |
存储过程 | /*!mycat: sql=select * from customer where id =1 */ CREATE PROCEDURE test_proc() BEGIN END ; |
多表Join | /*!mycat:catlet=io.mycat.catlets.ShareJoin */ |
支持insert select | /*!mycat: sql=select * from customer where id =1 */ INSERT INTO test2(id) SELECT id FROM order_detail; |
从写节点读取数据(配置读写分离后,默认从读节点读取) | /*balance*/ |
读写分离数据库选择( 1.6 版本之后) | /*#mycat: db_type=slave */(不被 mysql 单库兼容) /*#mycat: db_type=slave */ select * from customer;(不被 MyBatis 兼容) |
三.原理
Mycat 在执行 SQL 之前会先解析 SQL 语句,在获得分片信息后再到对应的物理节点上执行。如果 SQL 语句无法解析,则不能被执行。 如果语句中有注解,则会先解析注解的内容获得分片信息,再把真正需要执行的 SQL 语句发送到对应的物理节点上。
所以我们在使用注解的时候,应该清楚地知道目标 SQL 应该在哪个节点上执行,注解的 SQL 也指向这个分片,这样才能使用。如果注解没有使用正确的条件,会导致原始SQL 被发送到所有的节点上执行,造成数据错误