1

在查看 mysql 服务器和客户端协议时,我在 Ok_Packet 中找到了“受影响的行”“last-insert-id”两列。
我知道 Ok_packet 是由服务器发送给客户端的,作为客户端发送的命令的响应。对客户来说似乎没用。 在此处输入图像描述来自mysql-doc

我想知道它们到底是用来做什么的?

对此的任何想法将不胜感激。

4

1 回答 1

2

有一次,你已经链接到这个关于 MySQL 客户端/服务器协议的优秀信息汇编,我在第一次阅读时得出的结论是,它比官方文档中的任何内容都更好地组织和更完整。

该协议支持以不止一种方式做许多不同的事情......例如,您可以通过发送COM_DROP_DB仅包含 0x06 和数据库名称的数据包来删除数据库,以及发送COM_QUERY包含0x03 后跟字符串“DROP DATABASE schema_name”,FLUSH TABLES只需发送 0x07 0x04 即可执行。

rows_affected 和 last_insert_id 的每个 OK 数据包返回给客户端的两个值对客户端特别有用,因为它们允许您获得两条常用的信息,而无需转身询问它们。

每次查询后,您可以转身发送另一个查询:

SELECT ROW_COUNT(), LAST_INSERT_ID();

...但为什么?这是另一个通过网络到服务器的往返,另一个要解析的查询和另一个要生成的响应消息,所有这些都是不必要的。

其中一个一直在使用,你可能没有想太多:

mysql> DELETE FROM t1 WHERE id = 6;
Query OK, 1 row affected (0.09 sec)

服务器发送“查询正常,1 行受影响”。它发送了一个 OK 数据包,其中 rows_affected 值设置为 1。客户端将其转换为您看到的消息。客户也做了时间安排。

您可以从一般查询日志中确认客户端没有发送SELECT ROW_COUNT();得到那个值。

许多库公开了一种方法,该方法返回受影响的行或最后一个插入 ID,而无需将查询发送回服务器来询问它。在我看来,即使在不需要时,服务器自发发送此信息的低成本似乎也比必须制作并将另一个查询发送回服务器以获取相同信息更可取。

我想你也会发现你对二进制日志仍然有些困惑,它不是包含协议事务的日志。二进制日志与客户端/服务器协议共享许多数据结构,但它与客户端/服务器协议是一个独立的并且不是特别密切相关的东西。binlog 包含服务器上发生的更改的顺序记录,从属服务器可以使用它来将相同的更改应用于其自己的数据,这些更改已应用于主服务器,从而随着时间的推移保持两台服务器的数据集相同。 ..但它仅包含服务器上发生的更改,并且它们记录在称为“事件”的结构组中... 并且更改可以记录为在主服务器上执行的实际删除/插入/更新语句(基于语句的日志记录),或者记录为只包含更改的实际行中的实际数据的行图像(基于行记录)。在基于行的日志记录中,在协议中找不到列名,因为列是由它们的序号位置引用的,而这正是复制所需要的。当然,客户端/服务器协议的一小部分用于从属连接到主控并接收事件流,但这可能是为了方便而不是必要。因为这些列是由它们的序号位置引用的,这就是复制所需要的。当然,客户端/服务器协议的一小部分用于从属连接到主控并接收事件流,但这可能是为了方便而不是必要。因为这些列是由它们的序号位置引用的,这就是复制所需要的。当然,客户端/服务器协议的一小部分用于从属连接到主控并接收事件流,但这可能是为了方便而不是必要。

于 2013-12-06T03:46:48.820 回答