前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >快速学习-Mycat 注解

快速学习-Mycat 注解

作者头像
cwl_java
发布2021-12-30 17:33:52
3360
发布2021-12-30 17:33:52
举报
文章被收录于专栏:cwl_Javacwl_Java

第 5 章 Mycat 注解

5.1 注解原理

概念: MyCat 对自身不支持的 Sql 语句提供了一种解决方案——在要执行的 SQL 语句前添加额外的一段由注解SQL 组织的代码,这样 Sql 就能正确执行,这段代码称之为“注解”。注解的使用相当于对 mycat 不支持的 sql语句做了一层透明代理转发,直接交给目标的数据节点进行 sql 语句执行,其中注解 SQL 用于确定最终执行 SQL的数据节点。注解的形式是:

代码语言:javascript
复制
/*!mycat: sql=注解 Sql 语句*/

注解的使用方式是:

代码语言:javascript
复制
/*!mycat: sql=注解 Sql 语句*/

真正执行 Sql使用时将=号后的“注解 Sql 语句”替换为需要的 Sql 语句即可,后面会提到具体的用法。

原理: MyCat 执行 SQL 语句的流程是先进行 SQL 解析处理,解析出分片信息(路由信息)后,然后到该分片对应的物理库上去执行;若传入的 SQL 语句 MyCat 无法解析,则 MyCat 不会去执行;而注解则是告诉 MyCat 按照注解内的 SQL(称之为注解 SQL)去进行解析处理,解析出分片信息后,将注解后真正要执行的 SQL 语句(称之为原始 SQL)发送到该分片对应的物理库上去执行。

从上面的原理可以看到,注解只是告诉 MyCat 到何处去执行原始 SQL;因而使用注解前,要清楚的知道该原始 SQL 去哪个分片执行,然后在注解 SQL 中也指向该分片,这样才能使用!例子中的 sharding_id=10010 即是指明分片信息的。

需要说明的是,若注解 SQL 没有能明确到具体某个分片,譬如例子中的注解 SQL 没有添加sharding_id=10010 这个条件,则 MyCat 会将原始 SQL 发送到 persons 表所在的所有分片上去执行去,这样造成的后果若是插入语句,则在多个分片上都存在重复记录,同样查询、更新、删除操作也会得到错误的结果!

  • 解决问题:
  1. MySql 不支持的语法结构,如 insert …select…;
  2. 同一个实例内的跨库关联查询,如用户库和平台库内的表关联;
  3. 存储过程调用;
  4. 表,存储过程创建。
  • 注解规范
  1. 注解 SQL 使用 select 语句,不允许使用 delete/update/insert 等语句;虽然 delete/update/insert 等 语句也能用在注解中,但这些语句在 Sql 处理中有额外的逻辑判断,从性能考虑,请使用 select 语句
  2. 注解 SQL 禁用表关联语句;
  3. 注解 SQL 尽量用最简单的 SQL 语句,如 select id from tab_a where id=’10000’;
  4. 无论是原始 SQL 还是注解 SQL,禁止 DDL 语句;
  5. 能不用注解的尽量不用;
  6. 详细要求见下表。
在这里插入图片描述
在这里插入图片描述

补充说明: 使用注解并不额外增加 MyCat 的执行时间;从解析复杂度以及性能考虑,注解 SQL 应尽量简单。至于一个SQL 使用注解和不使用注解的性能对比,不存在参考意义,因为前提是 MyCat 不支持的 SQL 才使用注解。

5.2 注解使用示例

注解支持的’!‘不被 mysql 单库兼容, 注解支持的’#'不被 mybatis 兼容 新增加 mycat 字符前缀标志 Hintsql:"/** mycat: */" 从 1.6 开始支持三种注解方式:

代码语言:javascript
复制
/*#mycat:db_type=master*/ select * from travelrecord
/*!mycat:db_type=slave*/ select * from travelrecord
/**mycat:db_type=master*/ select * from travelrecord
  1. Mycat 端执行存储创建表或存储过程为: 存储过程:
代码语言:javascript
复制
/*!mycat: sql=select 1 from test */ CREATE PROCEDURE `test_proc`() BEGIN END ;

表:

代码语言:javascript
复制
/*!mycat: sql=select 1 from test */create table test2(id int);

注意注解中语句是节点的表请替换成自己表如 select 1 from 表 ,注解内语句查出来的数据在哪个分片,数据在那个节点往哪个节点建.

  1. 特殊语句自定义分片:
代码语言:javascript
复制
/*!mycat: sql=select 1 from test */insert into t_user(id,name) select id,name from t_user2;
  1. 读写分离 配置了 Mycat 读写分离后,默认查询都会从读节点获取数据,但是有些场景需要获取实时数据,如果从读节点获取数据可能因延时而无法实现实时,Mycat 支持通过注解/balance/来强制从写节点查询数据:
代码语言:javascript
复制
a. 事务内的 SQL,默认走写节点,以注解/*balance*/开头,则会根据 schema.xml 的 dataHost 标签属性的
balance=“1”或“2”去获取节点
b. 非事务内的 SQL,开启读写分离默认根据 balance=“1”或“2”去获取,以注解/*balance*/开头则会走写节
点解决部分已经开启读写分离,但是需要强一致性数据实时获取的场景走写节点
/*balance*/ select a.* from customer a where a.company_id=1;
  1. 多表 ShareJoin
代码语言:javascript
复制
/*!mycat:catlet=demo.catlets.ShareJoin */ select a.*,b.id, b.name as tit from customer a,company b on
a.company_id=b.id;

5.读写分离数据源选择

代码语言:javascript
复制
/*!mycat:db_type=master*/ select * from travelrecord
/*!mycat:db_type=slave*/ select * from travelrecord
/*#mycat:db_type=master*/ select * from travelrecord
/*#mycat:db_type=slave*/ select * from travelrecord
  1. 多租户支持 通过注解方式在配置多个 schema 情况下,指定走哪个配置的 schema。
  • web 部分修改: a.在用户登录时,在线程变量(ThreadLocal)中记录租户的 id b.修改 jdbc 的实现:在提交 sql 时,从 ThreadLocal 中获取租户 id, 添加 sql 注释,把租户的 schema放到注释中。例如:/*!mycat : schema = test_01 */ sql ;
  • 在 db 前面建立 proxy 层,代理所有 web 过来的数据库请求。proxy 层是用 mycat 实现的,web 提交的 sql 过来时在注释中指定 schema, proxy 层根据指定的 schema 转发 sql 请求。
代码语言:javascript
复制
/*!mycat : schema = test_01 */ sql ;
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-02-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第 5 章 Mycat 注解
    • 5.1 注解原理
      • 5.2 注解使用示例
      相关产品与服务
      云数据库 SQL Server
      腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档