MySQL SQL 格式化工具

粘贴一段 MySQL 查询——哪怕是直接从应用日志里复制、还带着 ? 占位符的那种——就能得到可读且格式一致的 SQL。反引号标识符和 MySQL 特有的函数都会被保留。

一条 MySQL 查询,格式化前后对比

下面这条未格式化的查询就是上方编辑器里加载的示例,输出则是本工具在默认选项下返回的原始结果,没有任何手工修饰。

粘贴进来的内容
SELECT `u`.`id`, `u`.`name`, count(o.id) AS orders, sum(o.total) AS revenue FROM `users` `u` LEFT JOIN `orders` `o` ON o.user_id = u.id WHERE u.created_at >= ? AND u.status = ? AND o.region IN (?) GROUP BY u.id, u.name HAVING sum(o.total) > ? ORDER BY revenue DESC LIMIT 50
格式化后的输出
SELECT
  `u`.`id`,
  `u`.`name`,
  count(o.id) AS orders,
  sum(o.total) AS revenue
FROM
  `users` `u`
  LEFT JOIN `orders` `o` ON o.user_id = u.id
WHERE
  u.created_at >= ?
  AND u.status = ?
  AND o.region IN (?)
GROUP BY
  u.id,
  u.name
HAVING
  sum(o.total) > ?
ORDER BY
  revenue DESC
LIMIT
  50

它能处理的 MySQL 语法

通用格式化工具往往会破坏方言特有的语法,或者干脆拒绝处理。以下是本工具针对 MySQL 做过测试的语法结构。

?

位置占位符按它们所紧邻的列和运算符分组,因此被比较两次的列只需填写一次。

`identifier`

反引号标识符会保留引用符号和大小写。

ON DUPLICATE KEY UPDATE

MySQL 独有的语句子句会被格式化,而不是当作一整块原样透传。

STRAIGHT_JOIN

MySQL 的连接提示和索引提示会原地保留。

MySQL 格式化工具常见问题

我能把日志里带 ? 占位符的查询直接粘进来吗?

可以,这正是常见用法。? 占位符会被检测出来,并按它们所比较的列分组,因此重复出现的列只需填写一次。之后把输出切换为填值 SQL,就能得到一条可执行的查询。

MariaDB 也适用吗?

适用——需要 MariaDB 特有关键字时,在方言列表中选择 MariaDB;若只涉及共通语法,用 MySQL 即可。

反引号包起来的标识符大小写会被保留吗?

会。关键字大小写和标识符大小写是两个独立选项,你可以把 SELECT 和 JOIN 变成大写,同时让 userProfile 这样的列名保持驼峰。这一点在 MySQL 上比别处更要紧,因为表名是否区分大小写取决于服务器的文件系统。

能把 MySQL 查询压缩回一行吗?

能。压缩会把查询收紧,方便粘回应用代码,并且绝不会改写字符串字面量内部的空白——与一个含两个空格的值做比较,压缩后返回的行依然相同。

能格式化从日志行里截出来的片段吗?

能。部分查询——或者只有 WHERE u.created_at >= ? AND u.status = ?——不需要外层的 SELECT 也能格式化并编辑。MySQL 慢查询日志和通用日志的输出正是这种形态,这个格式化工具就是为这种情况设计的。

支持 ON DUPLICATE KEY UPDATE 和索引提示吗?

支持。MySQL 独有的子句会被当作真正的子句来格式化,而不是作为一整块未格式化的文本原样带过;STRAIGHT_JOIN、FORCE INDEX 这类连接或索引提示也会紧跟在它们修饰的表后面。