Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

6.5.1.6 mysql 客户端技巧

本节提供了有关使用 mysql 的技术信息,以及 mysql 的操作行为。

输入行编辑

mysql 支持输入行编辑,可以在当前输入行中修改或回忆以前的输入行。例如,左箭头右箭头 键水平移动当前输入行,而 上箭头下箭头 键在以前输入的行中上下移动。退格 删除光标前的字符,输入新字符将其输入到光标位置。要输入行,请按 Enter

在 Windows 上,编辑键序列与控制台窗口中的命令编辑相同。在 Unix 上,键序列取决于用于构建 mysql 的输入库(例如,libeditreadline 库)。

有关 libeditreadline 库的文档在线提供。要更改给定输入库允许的键绑定,请在库启动文件中定义键绑定。这是一个位于家目录中的文件:.editrc 对于 libedit.inputrc 对于 readline

例如,在 libedit 中,Control+W 删除当前光标前的所有内容,而 Control+U 删除整个行。在 readline 中,Control+W 删除光标前的单词,而 Control+U 删除当前光标前的所有内容。如果 mysql 使用 libedit 构建,用户可以在 .editrc 文件中添加以下行,以获得 readline 的行为:

bind "^W" ed-delete-prev-word
bind "^U" vi-kill-line-prev

要查看当前的键绑定,请临时在 .editrc 文件末尾添加一行,仅包含 bindmysql 将在启动时显示绑定。

禁用交互式历史记录

使用 上箭头 键可以回忆当前和以前的输入行。在共享控制台的情况下,这种行为可能不适合。mysql 支持禁用交互式历史记录,部分或完全禁用,取决于主机平台。

在 Windows 上,历史记录存储在内存中。Alt+F7 删除当前历史记录缓冲区中的所有输入行,也删除了使用 F7 显示的顺序号列表,并使用 F9 回忆的输入行。新的输入行在按下 Alt+F7 后重新填充当前历史记录缓冲区。清除缓冲区不会阻止记录到 Windows 事件查看器,如果使用 --syslog 选项启动 mysql。关闭控制台窗口也清除当前历史记录缓冲区。

要在 Unix 上禁用交互式历史记录,首先删除 .mysql_history 文件,如果它存在(否则之前的条目将被回忆)。然后,使用 --histignore="*" 选项启动 mysql,以忽略所有新的输入行。要重新启用回忆(和日志记录)行为,请重新启动 mysql,而不使用该选项。

如果您阻止创建 .mysql_history 文件(请参阅 Controlling the History File),并使用 --histignore="*" 选项启动 mysql 客户端,则交互式历史记录回忆功能将被完全禁用。否则,如果您省略 --histignore 选项,您可以回忆当前会话期间输入的行。

Windows 上的 Unicode 支持

Windows 提供基于 UTF-16LE 的 API 来读取和写入控制台;mysql 客户端可以使用这些 API。Windows 安装程序在 MySQL 菜单中创建一个名为 MySQL 命令行客户端 - Unicode 的项目项。该项目项使用 Unicode 启动 mysql 客户端,以便与 MySQL 服务器通信。

要手动利用该支持,请在使用 Unicode 字符集的控制台中运行 mysql

  1. 打开控制台窗口。

  2. 转到控制台窗口属性,选择字体选项卡,并选择 Lucida Console 或其他兼容的 Unicode 字体。这是必要的,因为控制台窗口默认使用不适合 Unicode 的 DOS 光栅字体。

  3. 使用 mysql.exe--default-character-set=utf8mb4(或 utf8mb3)选项执行。这是必要的,因为 utf16le 是不能用作客户端字符集之一的字符集。请参阅 Impermissible Client Character Sets

使用这些更改,mysql 使用 Windows API 与控制台通信,使用 UTF-16LE,并使用 UTF-8 与服务器通信。(之前提到的菜单项设置字体和字符集,如上所述。)

要避免每次运行 mysql 时执行这些步骤,可以创建一个快捷方式,用于调用 mysql.exe。快捷方式应设置控制台字体为 Lucida Console 或其他兼容的 Unicode 字体,并传递 --default-character-set=utf8mb4(或 utf8mb3)选项给 mysql.exe

或者,创建一个快捷方式,仅设置控制台字体,并在 [mysql] 组的 my.ini 文件中设置字符集:

[mysql]
default-character-set=utf8mb4   # or utf8mb3
垂直显示查询结果

一些查询结果在垂直方向上显示更加易读,而不是在通常的水平表格格式中。可以通过在查询语句结尾使用\G而不是分号来垂直显示查询结果。例如,包含换行符的长文本值通常在垂直输出中更易读:

mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 LIMIT 300,1\G
*************************** 1. row ***************************
  msg_nro: 3068
     date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Jones
    reply: jones@example.com
  mail_to: "John Smith" <smith@example.com>
      sbj: UTF-8
      txt: >>>>> "John" == John Smith writes:

John> Hi.  I think this is a good idea.  Is anyone familiar
John> with UTF-8 or Unicode? Otherwise, I'll put this on my
John> TODO list and see what happens.

Yes, please do that.

Regards,
Jones
     file: inbox-jani-1
     hash: 190402944
1 row in set (0.09 sec)
使用安全更新模式(--safe-updates)

对于初学者,一个有用的启动选项是--safe-updates(或--i-am-a-dummy,它具有相同的效果)。安全更新模式对于防止意外更新或删除所有表行非常有帮助。通常,这些语句将更新或删除所有表行。使用--safe-updates,您只能通过指定标识要修改的行的键值、LIMIT子句或两者来修改行。这有助于防止事故。安全更新模式还限制了SELECT语句,生成(或估计生成)非常大的结果集。

使用--safe-updates选项时,mysql将在连接到MySQL服务器时执行以下语句,以设置会话值的sql_safe_updatessql_select_limitmax_join_size系统变量:

SET sql_safe_updates=1, sql_select_limit=1000, max_join_size=1000000;

使用SET语句影响语句处理如下:

  • 启用sql_safe_updates将导致UPDATEDELETE语句在没有在WHERE子句中指定键约束或提供LIMIT子句时产生错误,或者两者都提供。例如:

    UPDATE tbl_name SET not_key_column=val WHERE key_column=val;
    
    UPDATE tbl_name SET not_key_column=val LIMIT 1;
  • sql_select_limit设置为1,000将导致服务器限制所有SELECT结果集为1,000行,除非语句包括LIMIT子句。

  • max_join_size设置为1,000,000将导致多表SELECT语句在服务器估计需要检查超过1,000,000行组合时产生错误。

要指定不同的结果集限制,可以使用--select-limit--max-join-size选项在调用mysql时覆盖默认值:

mysql --safe-updates --select-limit=500 --max-join-size=10000

即使在安全更新模式下,UPDATEDELETE语句也可能在WHERE子句中指定键时产生错误,如果优化器决定不使用键列的索引:

这些行为包括在安全更新模式中:

  • EXPLAINUPDATEDELETE 语句不会产生安全更新错误。这使得可以使用 EXPLAINSHOW WARNINGS 来查看为什么索引未被使用,这在某些情况下非常有帮助,例如当 range_optimizer_max_mem_size 违规或类型转换发生时,优化器不会使用索引,即使在 WHERE 子句中指定了键列。

  • 当安全更新错误发生时,错误消息将包括第一个诊断信息,以提供有关失败原因的信息。例如,消息可能会指示 range_optimizer_max_mem_size 值被超过或类型转换发生,这两种情况都可能阻止使用索引。

  • 对于多表删除和更新,只有当目标表使用表扫描时,才会产生安全更新错误。

禁用 mysql 自动重新连接

如果 mysql 客户端在发送语句时失去与服务器的连接,它将立即自动尝试重新连接到服务器并重新发送语句。然而,即使 mysql 成功重新连接,前一个会话对象和设置将丢失:临时表、自动提交模式、用户定义和会话变量。此外,当前事务也将回滚。这可能对您非常危险,如下面的示例所示,其中服务器在第一和第二语句之间关闭并重新启动,而您不知道:

mysql> SET @a=1;
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO t VALUES(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: test

Query OK, 1 row affected (1.30 sec)

mysql> SELECT * FROM t;
+------+
| a    |
+------+
| NULL |
+------+
1 row in set (0.05 sec)

@a 用户变量已经随着连接丢失,并且在重新连接后未定义。如果您想让 mysql 在连接丢失时终止错误,可以使用 --skip-reconnect 选项启动 mysql 客户端。

有关自动重新连接对状态信息的影响的更多信息,请参阅 自动重新连接控制

mysql 客户端解析器与服务器解析器

mysql 客户端使用客户端解析器,而不是服务器端 mysqld 服务器使用的完整解析器。这可能导致对某些结构的不同处理。例如:

  • 服务器解析器将字符串用 " 字符分隔的字符串视为标识符,而不是普通字符串,如果启用了 ANSI_QUOTES SQL 模式。

    mysql 客户端解析器不考虑 ANSI_QUOTES SQL 模式。它将 ", '` 字符分隔的字符串视为相同的,不管 ANSI_QUOTES 是否启用。

  • /*! ... *//*+ ... */ 注释中,mysql 客户端解析器解释短形式 mysql 命令。服务器解析器不解释它们,因为这些命令在服务器端没有意义。

    如果希望 mysql 不在注释中解释短形式命令,可以使用 --binary-mode 选项,该选项会禁用所有 mysql 命令,除了非交互模式下 \C\d(用于输入到 mysql 或使用 source 命令加载)。