Documentation Home

4.5.1.6 mysql客户端提示

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

输入行编辑

mysql支持输入行编辑,这使您能够就地修改当前输入行或调用以前的输入行。例如, 箭头键和右箭头 键在当前输入行内水平移动,而 箭头键和下箭头键在先前输入的行集合中上下移动。 退格键删除光标前的字符,键入新字符会在光标位置输入新字符。要输入该行,请按Enter

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

libedit和 库的 文档readline可在线获取。要更改给定输入库允许的键序列集,请在库启动文件中定义键绑定。这是您主目录中的一个文件:.editrc forlibedit.inputrc for readline

例如,在 中libeditControl+W删除当前光标位置之前的所有内容,而Control+U删除整行。在readline中, Control+W删除光标前的单词,而Control+U删除当前光标位置之前的所有内容。如果mysql是使用 构建libedit的,则喜欢 readline这两个键的行为的用户可以将以下行放入.editrc文件中(必要时创建文件):

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

要查看当前的键绑定集,请暂时bind.editrc. 然后mysql 在启动时显示绑定。

禁用交互历史

向上箭头键使您能够从当前和以前 的会话中调用输入行。在共享控制台的情况下,此行为可能不合适。 mysql支持部分或全部禁用交互历史记录,具体取决于主机平台。

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

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

如果您阻止.mysql_history创建文件(请参阅控制历史文件)并用于--histignore="*"启动 mysql客户端,则交互式历史调用功能将完全禁用。或者,如果省略该 --histignore选项,则可以重新调用在当前会话期间输入的输入行。

Windows 上的 Unicode 支持

Windows 提供了基于 UTF-16LE 的 API,用于读取和写入控制台;Windows的mysql客户端能够使用这些 API。Windows 安装程序在 MySQL 菜单中创建一个名为MySQL command line client - Unicode. 此项调用带有属性集的 mysql客户端,以使用 Unicode 通过控制台与 MySQL 服务器通信。

要手动利用此支持,请在使用兼容 Unicode 字体的控制台中运行 mysql,并将默认字符集设置为支持与服务器通信的 Unicode 字符集:

  1. 打开控制台窗口。

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

  3. 使用 (或)选项 执行mysql.exe 。此选项是必需的,因为它是不能用作客户端字符集的字符集之一。请参阅 不允许的客户端字符集--default-character-set=utf8utf8mb4utf16le

通过这些更改,mysql可以使用 Windows API 使用 UTF-16LE 与控制台通信,并使用 UTF-8 与服务器通信。(前面提到的菜单项设置刚才描述的字体和字符集。)

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

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

[mysql]
default-character-set=utf8
垂直显示查询结果

一些查询结果在垂直显示时更具可读性,而不是通常的水平表格格式。通过使用 \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,效果相同)。安全更新模式对于您可能已发出 UPDATEor DELETE语句但忘记了WHERE指示要修改哪些行的子句的情况很有帮助。通常,此类语句会更新或删除表中的所有行。使用--safe-updates,您只能通过指定标识行的键值或LIMIT子句或两者来修改行。这有助于防止事故发生。安全更新模式还限制 SELECT产生(或估计产生)非常大的结果集的语句。

--safe-updates选项使 mysql在连接到 MySQL 服务器时执行以下语句,以设置 、 和系统变量的sql_safe_updates会话 sql_select_limitmax_join_size

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

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

  • 如果未在 子句中指定键约束或提供 子句或两者均未指定,则 启用sql_safe_updates 会导致UPDATE和 语句产生错误。例如: DELETEWHERELIMIT

    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子句。

  • 如果服务器估计它必须检查超过 1,000,000 行组合,则 设置max_join_size为 1,000,000 会导致多表 语句产生错误。SELECT

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

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

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

从 MySQL 5.7.25 开始,安全更新模式还包括以下行为:

  • EXPLAINwith UPDATEDELETE语句不会产生安全更新错误。这允许使用 EXPLAINplus 来查看未使用索引的原因,这在 发生违规或类型转换以及优化器不使用索引(即使在子句 中指定了键列)SHOW WARNINGS等情况下很有帮助 。range_optimizer_max_mem_sizeWHERE

  • 发生安全更新错误时,错误消息包括生成的第一个诊断信息,以提供有关失败原因的信息。例如,该消息可能表明 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因错误终止 很重要,您可以使用该 选项 启动mysql客户端 。--skip-reconnect

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

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

mysql客户端 在客户端使用的解析器不是 服务器端mysqld服务器使用的完整解析器的副本。这可能导致对某些构造的处理存在差异。例子:

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

    mysql客户端解析器不考虑 ANSI_QUOTESSQL 模式 。无论是否 启用 ,它都会将由"'和字符分隔的字符串视为相同。`ANSI_QUOTES

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

    如果希望mysql不解释注释中的短格式命令,部分解决方法是使用该 --binary-mode选项,这会导致所有mysql命令被禁用\C,但\d在非交互模式下(对于通过管道传输到 mysqlsource或使用命令加载 的输入) .