当前位置: 首页 > 面试题库 >

是否需要“ SET CHARACTER SET utf8”?

锺离嘉容
2023-03-14
问题内容

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

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

SET CHARACTER SET utf8必要吗?


问题答案:

利用SET CHARACTER SET utf8使用后SET NAMES utf8实际上会重置character_set_connection,并collation_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 = x同时在内部执行SET character_set_connection = <<character_set_of_collation_x>>SET character_set_connection = x内部还执行SET collation_connection = <<default_collation_of_character_set_x

所以基本上你重新character_set_connection@@character_set_databasecollation_connection@@collation_database。手册说明了这些变量的用法:

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

为此,服务器使用character_set_connection和collat​​ion_connection系统变量。它将客户端发送的语句从character_set_client转换为character_set_connection(具有诸如_latin1或_utf8之类的介绍符的字符串文字除外)。collat​​ion_connection对于比较文字字符串很重要。对于将字符串与列值进行比较,collat​​ion_connection无关紧要,因为列具有自己的排序规则,排序规则优先级更高。

综上所述,MySQL用于处理查询的编码/代码转换过程及其结果是一个多步骤的过程:

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

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

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

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



 类似资料:
  • 随着新的工具栏小部件的引入和AppCompat(android.support.v7.widget.Toolbar)版本的推出,是否还需要调用setSupportActionbar(工具栏)?或者调用setSupportActionbar有什么好处吗;现在我们可以设置标题、子标题、导航图标、导航图标单击侦听器(getSupportActionBar()。直接在工具栏上设置DisplayHomeAs

  • 问题内容: 我正在使用Hibernate Search,文档和书籍说我在id字段上需要@DocumentId,以便Hibernate Search可以知道如何将索引映射到对象。 没有代码中的@DocumentId,我的代码似乎运行良好。Hibernate Search是否变得足够聪明,以至于@Id字段是一个很好的默认值?是否会引起一些不明显的问题? 谢谢你的时间! 问题答案: 如果您使用的是老式的

  • 问题内容: 以下代码: 是/是打开JDBC连接所必需的。 我听说现代JDBC驱动程序不再需要它。但是我无法在项目中将其删除,因为我遇到了异常。我正在使用Java7和tomcat7。 什么时候可以省略构建? 问题答案: 从JDBC 4.0开始,不需要Class.forName()。 这是JDBC的Java教程的摘录。 在 早期 版本的JDBC中,要获得连接,首先必须通过调用方法Class.forNa

  • 问题内容: 我需要从该站点下载哪个tar? 我已经尝试过fortrans,但是一直出现此错误(明显地设置了环境变量之后)。 问题答案: 该SciPy的网页用来提供构建和安装说明,但说明现在依靠操作系统二进制分发。要在没有预编译所需库软件包的操作系统上构建SciPy(和NumPy),必须先构建然后静态链接到Fortran库BLAS和LAPACK: 仅执行五个g77 / gfortran / ifor

  • 问题内容: 这可能是愚蠢的问题。Hyperledger Fabric是否需要Docker才能运行。 我只是想知道,仅当我们需要在同一台物理机中将Fabric peer,orderer或benchDB作为虚拟机运行时才需要Docker。我认为,如果我们在单独的同一台服务器上本地安装这些软件(对等,订单,couchDB等),则可能不需要Docker。 谢谢。 问题答案: 只是要注意这一点,尽管您不需要

  • 我使用testAd ID(ca-app-pub-3940256099942544/1033173712)从admob不是我的admob ID,我需要使用addTestDevice()太,而在移动设备测试?它甚至显示了测试广告屏幕,而不是实时广告。 因为我这样做了,我整天都在使用我的应用程序进行测试,晚上我收到了账户暂停邮件。