8-TDengine里用的好好的字段名,却被MySQL的保留字狠狠上了一课

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 8-TDengine里用的好好的字段名,却被MySQL的保留字狠狠上了一课

背景


使用 TDengine 集成 MyBatistPlus 后,对我自己建的数据表进行分页查询时闪退,同时有条信息: Process finished with exit code -1073741819 (0xC0000005)


image.png

我们知道, MyBatistPlus 的分页查询时先查询记录的总数,再进行分页条件查询,仔细观察 MyBatistPlus 控制台日志生成的SQL语句: SELECT COUNT(1) FROM ( SELECT ts, voltage, current, temperature, sn, city, groupid FROM power ) TOTAL; ,直接将这条SQL语句放在 taos 的客户端命令行执行是正确的(当然,需要先切换至对应的数据库: use ok; )。


image.png


分析问题


  • 难道是环境问题?


统一了 SpringBootMyBatisPlustaos-jdbcdriver 的版本,以及JDK、编译器的版本,甚至将官方SpringBoot与 MyBatistPlus 集成的例子放进同一个项目, Temperature 可正常分页查询,可一到我的 Power 就不对了;所以是我的表有问题。


  • 难道是因为数据量太大?


自己建的表超过1亿条数据, 官方示例中的 Temperature 是用来测试的,里面总共就几张子表,数据量也是个位数,可我试了官方的 meters 表, 100000000 条数据,分页查询正常呀;所以是我的表有问题。


  • 难道是我建的表有问题?


是我建表方式有问题?可对照官网说明仔细检查了十来八遍,没发现建库、建表语句有啥问题。而且 TDengine 官方文档中也是有这样的示例的:


Note: 建库建表语句如下(以下是经过简化后的,仅写入两条数据,说明问题即可):

create database if not exists ok;
create stable if not exists ok.power(ts timestamp, voltage int, current float, temperature float) tags(sn int, city nchar(64), groupid int);
create table if not exists ok.device1 using ok.power tags(1, "太原", 1);
create table if not exists ok.device2 using ok.power tags(2, "西安", 2);
insert into ok.device1 values("2021-09-04 21:03:38.734", 1, 1.0, 1.0);
insert into ok.device2 values("2021-09-04 21:03:40.734", 2, 2.0, 2.0);

image.png

见鬼,我竟然开始怀疑人生了。


我决定跟踪下 MyBatisPlus 分页查询拦截器的源码,到底为啥我建的表会导致查询数据总量的SQL与别人的不一样。

-- 通过 `MyBatisPlus` 分页查询官方meter表生成的count查询语句
SELECT COUNT(1) FROM meters
-- 通过 `MyBatisPlus` 分页查询官方我建的表生成的count查询语句
SELECT COUNT(1) FROM ( SELECT ts, voltage, current, temperature, sn, city, groupid FROM power ) TOTAL


源码调试


从配置的分页拦截器位置开始,一步步调试。

image.png

image.png

image.png

image.png

image.png

image.png

net.sf.jsqlparser.parser. ParseException: Encountered unexpected token: "current"


当看到这个信息时,瞬间炸裂,一下子就知道错哪里了, current现在的;电流 的意思,当年也是虐过四六级的人。。这跟英语好不好没啥关系,而是跟编码基础与习惯、细心程度密切相关。这种细节错误很容易就被忽略,导致南辕北辙,耗费掉大半天时光。其实跟踪起来倒也不太难,只是刚开始没往这个方向思考。


JsqlParserCountOptimize里的parser方法,try中的第一行代码直接到了catch块里,显然,这第一行抛异常了。。

image.png

而且, IDEA 的高亮语法显示其实早已经标明了 current 是个关键字/保留字,只是,一开始的注意力根本没放在这里。

image.png


解决问题


显然,换个名字吧,字段名不能使用 mysql 的关键字以及保留字(虽然在 TDengine 中一切正常),一般遇到 order 这种关键字出现在表名、字段名中时,我们会用反引号括起来,但是这里通过分页插件的查询代码显然没帮我们做这件事。


这个问题的根本是我们不应该使用保留字 current 作为字段名,但引起麻烦的是这个分页插件并没有向我们显式的报错,而是仅展示了一段莫名其妙的信息: Process finished with exit code -1073741819 (0xC0000005) (网上查了下这个报错,很多说是跟金山词霸有关系,这个。。真心没用过)。


另外,如果使用 MyBatistPlusselectList 方法,则正常执行。。 sigh

image.png


总结


current 作为字段名在 TDengine 中正常,在 MySQL 中用反引号括起来也正常;然而,当 TDengine 集成 MyBatistPlus 后,分页查询时,问题出现了。。在 TDengine 里用的好好的字段名,却被 MySQL 狠狠上了一课。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
5月前
|
SQL 关系型数据库 MySQL
C++orm使用插曲——MySQL保留字
C++orm使用插曲——MySQL保留字
57 7
|
6月前
|
SQL 存储 关系型数据库
MySQL保留字和关键字怎么查询
【4月更文挑战第29天】
231 0
|
SQL 关系型数据库 MySQL
MySql 使用关键字做字段名
MySql 使用关键字做字段名
336 0
|
6月前
|
关系型数据库 MySQL
mysql及sqlserver修改字段名和字段长度
mysql及sqlserver修改字段名和字段长度
90 0
|
SQL 关系型数据库 MySQL
Mysql 关键字\保留字列表
Mysql 关键字\保留字列表
79 0
|
SQL 关系型数据库 MySQL
数据库设计:防止MySQL字段名与关键字相撞,保护数据完整性!
数据库设计:防止MySQL字段名与关键字相撞,保护数据完整性!
383 0
|
关系型数据库 MySQL
MySQL修改字段名、修改字段类型
MySQL修改字段名、修改字段类型
1097 0
MySQL修改字段名、修改字段类型
|
关系型数据库 MySQL 数据库
MySQL:修改表名和字段名和类型
MySQL:修改表名和字段名和类型
241 0
|
SQL Oracle 关系型数据库
MySQL - 查询数据库里所有表名和字段名
MySQL - 查询数据库里所有表名和字段名
502 0
下一篇
无影云桌面