“设置字符集 utf8”是否必要?

2022-08-30 14:43:37

我正在重写我们的数据库类(基于PDO),并陷入了困境。我被教导在PHP和MySQL中使用UTF-8和使用UTF-8。SET NAMES utf8SET CHARACTER SET utf8

在PDO中,我现在想要使用该参数,但它只支持一个查询。PDO::MYSQL_ATTR_INIT_COMMAND

有必要吗?SET CHARACTER SET utf8


答案 1

使用后使用实际上会分别重置 和 到
和。SET CHARACTER SET utf8SET NAMES utf8character_set_connectioncollation_connection@@character_set_database@@collation_database

手册指出

  • SET NAMES x等效于

    SET character_set_client = x;
    SET character_set_results = x;
    SET character_set_connection = x;
    
  • 并等效于SET CHARACTER SET x

    SET character_set_client = x;
    SET character_set_results = x;
    SET collation_connection = @@collation_database;
    

而内部也执行,内部也执行 。SET collation_connection = xSET character_set_connection = <<character_set_of_collation_x>>SET character_set_connection = xSET collation_connection = <<default_collation_of_character_set_x

因此,从本质上讲,您正在重置为 和 .本手册解释了这些变量的用法:character_set_connection@@character_set_databasecollation_connection@@collation_database

服务器在收到语句后应将语句转换为什么字符集?

为此,服务器使用character_set_connection和collation_connection系统变量。它将客户端发送的语句从 character_set_client 转换为 character_set_connection(具有引入符的字符串文本除外,如 _latin1 或 _utf8)。collation_connection对于文本字符串的比较非常重要。对于字符串与列值的比较,collation_connection并不重要,因为列具有自己的排序规则,而排序规则的优先级更高。

总而言之,MySQL用于处理查询及其结果的编码/转码过程是一个多步骤的事情:

  1. MySQL 将传入查询视为在 .character_set_client
  2. MySQL将语句从转码为character_set_clientcharacter_set_connection
  3. 将字符串值与列值进行比较时,MySQL将字符串值转码为给定数据库列的字符集,并使用列排序规则进行排序和比较。character_set_connection
  4. MySQL构建编码的结果集(这包括结果数据以及结果元数据,如列名等)character_set_results

因此,可能的情况是,a 不足以提供完整的 UTF-8 支持。考虑一下用 -charset 定义的默认数据库字符集和列,然后执行上述步骤。由于无法覆盖 UTF-8 可以覆盖的所有字符,因此可能会在步骤 3 中丢失字符信息。SET CHARACTER SET utf8latin1utf8latin1

  • 3 步:假设您的查询以 UTF-8 编码,并且包含无法用 表示的字符,则在转码为 to(默认数据库字符集)时,这些字符将丢失,从而导致查询失败。latin1utf8latin1

因此,我认为可以肯定地说,这是处理字符集问题的正确方法。尽管我可能会补充说,正确设置MySQL服务器变量(所有必需的变量都可以在中静态设置)可以使您免于每次连接所需的额外查询的性能开销。SET NAMES ...my.cnf


答案 2

来自 mysql 手册

SET 字符集类似于 SET NAMES,但 set and to 和 。语句等效于以下三个语句:character_set_connectioncollation_connectioncharacter_set_databasecollation_databaseSET CHARACTER SET x

SET character_set_client = x;
SET character_set_results = x;
SET collation_connection = @@collation_database;

推荐