新聞中心
前言
MySQL Server當(dāng)前支持如下3種注釋風(fēng)格:

成都創(chuàng)新互聯(lián)是網(wǎng)站建設(shè)技術(shù)企業(yè),為成都企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、網(wǎng)站制作,網(wǎng)站設(shè)計(jì),網(wǎng)站制作,網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制適合企業(yè)的網(wǎng)站。十多年品質(zhì),值得信賴!
- 以'#'開(kāi)頭的單行注釋
- 以'-- '開(kāi)頭的單行注釋
- C語(yǔ)言風(fēng)格的單行/多行注釋
如下SQL腳本給出了3種注釋風(fēng)格的示例:
/* 這是一個(gè)
多行注釋
示例
*/
select 1 from dual;
select 2 from dual; # 單行注釋用例1
select 3 from dual; -- 單行注釋用例2
可執(zhí)行注釋
為了支持在不同數(shù)據(jù)庫(kù)之間的可移植性,MySQL Server針對(duì)C風(fēng)格的注釋在解析上做了一些擴(kuò)展,當(dāng)注釋滿足如下風(fēng)格時(shí),MySQL Server將會(huì)解析并執(zhí)行注釋中的代碼:
/*! MySQL-specific code */
通過(guò)比較如下兩個(gè)帶注釋的SQL語(yǔ)句的執(zhí)行結(jié)果可以比較直觀地看出可執(zhí)行注釋語(yǔ)句的行為:
# 普通注釋,'+1' 被忽略
mysql> select 1 /* +1 */;
+---+
| 1 |
+---+
| 1 |
+---+
# 可執(zhí)行注釋,'+1' 被當(dāng)成語(yǔ)句的一部分
mysql> select 1 /*! +1 */;
+-------+
| 1 +1 |
+-------+
| 2 |
+-------+
借助這一特性,我們就有機(jī)會(huì)編寫(xiě)具備較好移植性的SQL語(yǔ)句, 在使用MySQL獨(dú)有特性的同時(shí),保證了SQL語(yǔ)句在其它數(shù)據(jù)庫(kù)也能夠成功被執(zhí)行:
create table t1(col1 int) /*! engine=MyISAM */;
select /*! STRAIGHT_JOIN */ col1 from t1;
...
/*!version-number SQL*/
在日常使用中,我們還會(huì)經(jīng)常看到如下格式的注釋語(yǔ)句:
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE */
/*!80000 SET SESSION information_schema_stats_expiry=0 */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
/*!后跟的5位數(shù)字為版本指示器,其與數(shù)據(jù)庫(kù)版本的對(duì)應(yīng)規(guī)則為:
'/' '*' '!', followed by exactly
第1位:主版本號(hào)(VERSION_MAJOR),
第2, 3位:小版本號(hào)(VERSION_MINOR),
第4, 5位:Patch號(hào)(VERSION_PATCH)
示例:
32302 -> 3.23.02
50738 -> 5.7.38
80025 -> 8.0.25
以上述第一個(gè)注釋語(yǔ)句為例,它的含義可以描述為:當(dāng)MySQL數(shù)據(jù)庫(kù)版本為5.0.3或更高版本時(shí),將SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE讀取出來(lái)參與SQL語(yǔ)法解析,并最終被執(zhí)行;當(dāng)MySQL版本低于5.0.3時(shí),該行語(yǔ)句被當(dāng)成一個(gè)普通的注釋。不難看出,帶version_number的可執(zhí)行注釋,是為了解決不同的MySQL版本之間的兼容問(wèn)題。以8.0.23版本新增的Invisible Columnsw為例, 如下建表語(yǔ)句在8.0.23版本之前將無(wú)法執(zhí)行:
CREATE TABLE t1 (i INT, j DATE INVISIBLE);
如下的語(yǔ)句改造則保證了建表語(yǔ)句的向下版本兼容:
CREATE TABLE t1 (i INT, j DATE /*!80023 INVISIBLE */);
實(shí)際上,在我們常用的工具mysqldump也借用這個(gè)特性,使得產(chǎn)生的SQL能夠兼容不同的數(shù)據(jù)庫(kù)版本:
/*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等語(yǔ)句中我們也能看到類似的應(yīng)用(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)
結(jié)語(yǔ)
MySQL Server提供的可執(zhí)行注釋功能,在橫向跨數(shù)據(jù)庫(kù)和縱向跨版本兼容上都為數(shù)據(jù)庫(kù)用戶提供了較大支持,是一個(gè)比較便利的特性。功能實(shí)現(xiàn)上,MySQL Server是在詞法解析階段先對(duì)語(yǔ)句做了一遍攔截,針對(duì)/*!按具體情況做了特殊處理,如有興趣您可以參考MySQL的詞法解析相關(guān)源碼。注:以8.0.25版本為例,它的相關(guān)解析放在sql_lex.cc的lex_one_token()中,在其中您也能看見(jiàn)MySQL詞法解析器是怎么對(duì)optimizer hints comments(格式: /*+ optimizer_hints */ )進(jìn)行處理的。
當(dāng)前題目:聊聊MySQLServer可執(zhí)行注釋,你懂了嗎?
路徑分享:http://fisionsoft.com.cn/article/cojoodh.html


咨詢
建站咨詢
