聊聊 MySQL Server 可执行注释,你懂了吗?

发布时间:2025-05-17 22:07:04 作者:益华网络 来源:undefined 浏览量(1) 点赞(1)
摘要:前言MySQL Server当前支持如下3种注释风格:以#开头的单行注释以-- 开头的单行注释C语言风格的单行/多行注释如下SQL脚本给出了3种注释风格的示例: /* 这是一个 多行注释 示例 */ select 1 from dual; select 2 from dual; # 单行注释用例1select 3 from du

前言

MySQL Server当前支持如下3种注释风格:

以#开头的单行注释以-- 开头的单行注释C语言风格的单行/多行注释

如下SQL脚本给出了3种注释风格的示例:

/* 这是一个

多行注释

示例

*/

select 1 from dual;

select 2 from dual; # 单行注释用例1

select 3 from dual; -- 单行注释用例2可执行注释

为了支持在不同数据库之间的可移植性,MySQL Server针对C风格的注释在解析上做了一些扩展,当注释满足如下风格时,MySQL Server将会解析并执行注释中的代码:

/*! MySQL-specific code */

通过比较如下两个带注释的SQL语句的执行结果可以比较直观地看出可执行注释语句的行为:

# 普通注释,+1 被忽略

mysql> select 1 /* +1 */;

+---+

| 1 |

+---+

| 1 |

+---+

# 可执行注释,+1 被当成语句的一部分

mysql> select 1 /*! +1 */;

+-------+

| 1 +1 |

+-------+

| 2 |

+-------+

借助这一特性,我们就有机会编写具备较好移植性的SQL语句, 在使用MySQL独有特性的同时,保证了SQL语句在其它数据库也能够成功被执行:

create table t1(col1 int) /*! engine=MyISAM */;

select /*! STRAIGHT_JOIN */ col1 from t1;

.../*!version-number SQL*/

在日常使用中,我们还会经常看到如下格式的注释语句:

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE */

/*!80000 SET SESSION information_schema_stats_expiry=0 */

/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */

/*!后跟的5位数字为版本指示器,其与数据库版本的对应规则为:

/ * !, followed by exactly

第1位:主版本号(VERSION_MAJOR),

第2, 3位:小版本号(VERSION_MINOR),

第4, 5位:Patch号(VERSION_PATCH)

示例:

32302 -> 3.23.02

50738 -> 5.7.38

80025 -> 8.0.25

以上述第一个注释语句为例,它的含义可以描述为:当MySQL数据库版本为5.0.3或更高版本时,将SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE读取出来参与SQL语法解析,并最终被执行;当MySQL版本低于5.0.3时,该行语句被当成一个普通的注释。不难看出,带version_number的可执行注释,是为了解决不同的MySQL版本之间的兼容问题。以8.0.23版本新增的Invisible Columnsw为例, 如下建表语句在8.0.23版本之前将无法执行:

CREATE TABLE t1 (i INT, j DATE INVISIBLE);

如下的语句改造则保证了建表语句的向下版本兼容:

CREATE TABLE t1 (i INT, j DATE /*!80023 INVISIBLE */);

实际上,在我们常用的工具mysqldump也借用这个特性,使得产生的SQL能够兼容不同的数据库版本:

/*mysqldump 代码片段*/

dump_fputs(

sql_file,

"/*!50717 SELECT COUNT(*) INTO @rocksdb_has_p_s_session_variables"

" FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA ="

" performance_schema AND TABLE_NAME = session_variables"

" */;\n"

"/*!50717 SET @rocksdb_get_is_supported = IF"

" (@rocksdb_has_p_s_session_variables, SELECT COUNT(*) INTO"

" @rocksdb_is_supported FROM performance_schema.session_variables"

" WHERE VARIABLE_NAME=\\rocksdb_bulk_load\\, SELECT 0) */;\n"

"/*!50717 PREPARE s FROM @rocksdb_get_is_supported */;\n"

"/*!50717 EXECUTE s */;\n"

"/*!50717 DEALLOCATE PREPARE s */;\n"

"/*!50717 SET @rocksdb_enable_bulk_load = IF"

" (@rocksdb_is_supported, SET SESSION rocksdb_bulk_load = 1,"

" SET @rocksdb_dummy_bulk_load = 0) */;\n"

"/*!50717 PREPARE s FROM @rocksdb_enable_bulk_load */;\n"

"/*!50717 EXECUTE s */;\n"

"/*!50717 DEALLOCATE PREPARE s */;\n");

check_io(sql_file);

在show create table等语句中我们也能看到类似的应用(sql/sql_show.cc):

mysql> create table t1 (i int, j date invisible);

Query OK, 0 rows affected (0.03 sec)

mysql> show create table t1;

+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+

| Table | Create Table |

+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+

| t1 | CREATE TABLE `t1` (

`i` int DEFAULT NULL,

`j` date DEFAULT NULL /*!80023 INVISIBLE */

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |

+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.01 sec)结语

MySQL Server提供的可执行注释功能,在横向跨数据库和纵向跨版本兼容上都为数据库用户提供了较大支持,是一个比较便利的特性。功能实现上,MySQL Server是在词法解析阶段先对语句做了一遍拦截,针对/*!按具体情况做了特殊处理,如有兴趣您可以参考MySQL的词法解析相关源码。注:以8.0.25版本为例,它的相关解析放在sql_lex.cc的lex_one_token()中,在其中您也能看见MySQL词法解析器是怎么对optimizer hints comments(格式: /*+ optimizer_hints */ )进行处理的。

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!