我昨天问的一个问题的一个回答建议我应该确保我的数据库能够正确处理UTF-8字符。如何使用MySQL?
- 我真的希望我们得到一个全面的答案,包括各种MySQL版本、不兼容等。
- 另请参见stackoverflow.com/questions/2344118/utf-8-general-bin-unicod‌&8203;e
- @杨爱德华兹(Edwardz.Yang)--MySQL4.1引入了CHARACTER SETs;5.1.24对德国夏普-S(&223;)的排序进行了混乱,通过在5.1.62中添加另一个排序进行了纠正(可以说会使情况更糟);5.5.3用新的字符集utf8mb4填充了utf8。
- 这个问题和这个问题完全一样。请看stackoverflow.com/questions/3513773/…
- 值得指出的是,这些答案中的大多数都是明显错误的。不要使用utf8。它最多只支持3个字节的字符。在mysql中应该使用的正确字符集是utf8mb4。
更新:
简短的回答-您几乎应该总是使用utf8mb4字符集和utf8mb4_unicode_ci排序规则。
要更改数据库:
见:
Aaron对这个答案的评论如何使MySQL正确处理UTF-8
utf8_-general_-ci和utf8_-unicode_-ci有什么区别?
转换指南:https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-conversion.html
原始答案:
MySQL4.1及以上版本的默认字符集为utf-8。您可以在my.cnf文件中对此进行验证,记住同时设置客户机和服务器(default-character-set和character-set-server。
如果您有要转换为UTF-8的现有数据,请转储数据库,并将其导入回UTF-8,确保:
- 查询/插入数据库前使用SET NAMES utf8。
- 创建新表时使用DEFAULT CHARSET=utf8。
- 此时,您的MySQL客户机和服务器应该使用UTF-8(请参见my.cnf)。记住,您使用的任何语言(如PHP)也必须是UTF-8。某些版本的PHP将使用自己的MySQL客户机库,这可能不支持UTF-8。
如果要迁移现有数据,请记住首先备份!当事情没有按计划进行时,可能会发生很多奇怪的数据切割!
一些资源:
- 完成UTF-8迁移(cdbaby.com)
- 关于PHP函数的UTF-8就绪性的文章(请注意,其中一些信息已经过时了)
- 我的理解是,MySQL中的utf8只指完整Unicode的一小部分。您应该使用utf8mb4来强制提供完全支持。参见mathiasbynens.be/notes/mysql-utf8mb4"很长一段时间以来,我一直在使用mysql的utf8字符集来处理数据库、表和列,假设它映射到上面描述的utf-8编码。"
- MySQL从来没有默认的utf-8字符集。4.1和5.x到最新的5.7都使用latin1和latin1_swedish_ci作为默认字符集和排序规则。请参见MySQL手册中的"服务器字符集和排序规则"页面进行确认:dev.mysql.com/doc/refman/5.1/en/charset-server.html
- (蒂姆的评论消失了!但我认为我在这里的回答可能对一些人仍然有用。这里是:)根据维基百科,5字节和6字节的编码已经被删除。它们实际上从未被使用过。Unicode从未定义使用5字节或6字节编码的字符范围。我认为这封电子邮件最能说明问题
- @是的,我在读了维基百科的那篇文章后删除了它。;)
- 在mysql中,utf8最令人讨厌的方面是必须为表中的每个可能的字符保留3或4个字节。因此,utf8mb4意味着,如果使用最大行长度,则只能将常规英语文本的1/4保存为latin1。我想这就是为什么很多程序放弃使用二进制文件,如果它们有很多文本需要保存的话。(维基百科就是一个例子)
- @Timtisdall当大多数文本是ASCII时,您不必担心utf8mb4会占用额外的存储空间。虽然char字符串是预先分配的,但varchar字符串不是--请参阅本文档页的最后几行。例如,在utf8mb4下,char(10)将悲观地保留40个字节,但varchar(10)将根据可变长度编码分配字节。
- @凯文,我想你误读了。我认为最大行长度是64K。您只能将utf8mb4字段设置为该字段的1/4,因为它必须保留足够的空间。所以,即使是ASCII,也只能插入16K字符。
- @Timtisdall哦,你说的是上界。是的,那些比较低。幸运的是,如果您试图将varchar(n)字段更改为大于可行字节大小(同时发出警告),MySQL的当前版本将自动从varchar(n)升级到text数据类型。索引也将有一个较低的最坏情况上限,这可能会出现其他问题。
- 声明"…根据MySQL自己的文档:dev.mysql.com/doc/refman/4.1/en/charset-unicode-utf8.html,默认的utf-8"字符集不正确-它根本不允许4字节字符。
- 不要使用utf8。使用utf8mb4。在表锁定和CPU时间方面,转换字符集已经很昂贵了。不要为不支持所有字符的劣质字符集操心。
- 检查mysql当前是否使用utf8[mb4]或latin1,使用show变量,例如SHOW VARIABLES WHERE Value LIKE 'latin1%';。下面是另一篇关于如何在my.cnf中配置utf8mb4的文章。
在my.cnf中,要使这一点成为"永久性"的:
1 2 3 4
| [client ]
default-character -set=utf8
[mysqld ]
character -set -server = utf8 |
号
要进行检查,请转到客户机并显示一些变量:
验证它们都是utf8,除了..._filesystem,应该是binary和..._dir,这在mysql安装中有所体现。
- 它在我的案例中不起作用,但我还是用给定的内容创建了文件my.cf in/etc。我用的是create table my_name(field_name varchar(25) character set utf8);。
- "show variables like'character_set%';"命令显示了我的连接问题。谢谢!
- 这是不正确的。MySQL称之为utf8的不是"完整"的utf-8。
MySQL4.1及更高版本有一个默认字符集,它调用utf8,但实际上它只是utf-8的一个子集(只允许三个字节的字符和更小的字符)。
如果需要"完整"的UTF-8,请使用utf8mb4作为字符集。
- 遗憾的是,这是迄今为止唯一正确的答案。
- 当然同意,这是唯一正确的答案。utf8不包括表情符号。UTF8mb4有。有关如何更新的详细信息,请检查此项:mathiasbynens.be/notes/mysql-utf8mb4
- @basti——大部分都是正确的(直到最近Latin1还是默认值),并且没有完成(没有讨论正确插入/选择utf8编码数据,也没有以HTML显示)。
- 尊敬的,@rickjames,巴斯蒂说:"到目前为止"——我不记得我发这个帖子时看到你的答案了。
- 唉,有大约5种明显不同的utf8问题症状,还有大约4种编程人员做错了会引起麻烦的事情。大多数答案只指出一件事可能需要解决。最初的问题很宽泛,所以答案需要全部4个。也许巴斯蒂熟悉一个症状,你的一个方面就是解决的办法。
- 或者,从另一个角度来看,"正确处理UTF-8字符"可以通过两种方式读取…你读到它需要utf8mb4。我读它是因为在进出数据库的过程中没有混淆文本。根据你和巴斯蒂的解释,你的回答是正确和完整的。
- 作为旁白,我想暂停一下,给MySQL团队一个非常好的、艰难的注视。你们在想什么?通过在程序"utf8"中创建一个实际上不是utf-8的代码页,您是否意识到自己带来了多大的困惑?该死的混蛋。< /咆哮>
简而言之:在4个位置使用utf8mb4:
- 客户机中的字节是utf8,而不是latin1/cp1251/etc。
- 当建立客户端与MySQL的连接时,SET NAMES utf8mb4或类似的东西
- 所有表/列上的CHARACTER SET utf8mb4--除了严格使用ASCII/Hex/Country_code/Zip_code/等的列。
- 如果输出到HTML,则返回。(是的,这里的拼写不同。)
更多信息;一路UTF8
上面的链接提供了"解决所有问题需要详细的规范化答案"。--这个论坛有空间限制。
编辑
除了包含"全"世界字符的CHARACTER SET utf8mb4外,COLLATION utf8mb4_unicode_520_ci也可以说是最好的全方位排序规则。(也有土耳其语、西班牙语等,供那些想要这些语言细微差别的人使用。)
- 关于如何从输出中调试UTF8问题的新链接。
- 为什么unicode__-ci不是最好的:stackoverflow.com/a/49982378/62202
- @路易斯-正如我所暗示的,西班牙和土耳其(以及波兰)用户可能不高兴。""最好的全面"往往会伤害到每个人一些。MySQL8.0有一个更新的"最佳"排序规则:utf8mb4_Ai_Ci。唉,又是L=?.
字符集是数据库(默认)和表的属性。您可以查看(mysql命令):
。
换句话说,检查或更改数据库字符集非常容易:
- 这是不正确的。MySQL称之为utf8的不是"完整"的utf-8。
要将数据库本身的字符集编码更改为utf-8,请在mysql>提示符下键入以下命令。使用ALTER DATABASE。将dbname替换为数据库名称:
这是这个问题的副本,如何将整个MySQL数据库字符集和排序规则转换为UTF-8?
我遵循了Javier的解决方案,但在my.cnf中添加了一些不同的行:
1 2 3 4
| [myslqd]
skip-character-set-client-handshake
collation_server=utf8_unicode_ci
character_set_server=utf8 |
。
我在这里找到了这个想法:http://dev.mysql.com/doc/refman/5.0/en/charset-server.html,在页面底部的第一个/唯一的用户注释中。他提到跳过字符集客户机握手具有一定的重要性。
- 这个不受欢迎的零投票答案是唯一帮助我的东西!所以它得到了我的选票,这是肯定的。埃多克斯1〔5〕是关键。
把你的database collation设为UTF-8。然后将table collation应用于数据库默认值。
这些关于mysql和utf-8的提示可能会有所帮助。不幸的是,它们并不构成一个完整的解决方案,只是常见的问题。
您的答案是可以通过MySQL设置进行配置。在我的回答中,可能有些事情是断章取义的,但这也知道对你有帮助。如何配置Character Set和Collation。
For applications that store data using the default MySQL character set
and collation (latin1, latin1_swedish_ci), no special configuration
should be needed. If applications require data storage using a
different character set or collation, you can configure character set
information several ways:
号
- 为每个数据库指定字符设置。例如,应用程序使用一个数据库可能需要utf8,而使用使用另一个数据库可能需要sjis。
- 在服务器启动时指定字符设置。这会导致服务器为所有不创建其他应用程序的应用程序使用给定的设置安排。
- 如果构建MySQL,请在配置时指定字符设置来源。这将导致服务器使用所有应用程序,无需在服务器启动时指定它们。
这里给出的示例可以让您的问题设置utf8字符集,这里也可以设置排序规则以获得更多帮助(utf8_general_cicollation`)。
为每个数据库指定字符设置
在服务器启动时指定字符设置
1 2 3
| [mysqld]
character-set-server=utf8
collation-server=utf8_general_ci |
号
在mysql配置时指定字符设置
1 2
| shell> cmake . -DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci |
要查看应用于连接的字符集和排序规则系统变量的值,请使用以下语句:
。
这可能是一个冗长的答案,但总有办法,你可以使用。希望我的回答对你有帮助。有关详细信息,请访问http://dev.mysql.com/doc/refman/5.7/en/charset-applications.html
到UTF-8的数据库连接
1 2 3
| $connect = mysql_connect ('$localhost','$username','$password') or die (mysql_error ());
mysql_set_charset ('utf8',$connect );
mysql_select_db ('$database_name','$connect') or die (mysql_error ()); |
。
埃多克斯1〔5〕
这就是窍门
- 虽然使用SET NAMES UTF8或UTF8mb4是正确的,但您不能解释它的作用(用于此连接的字符集)。"这样做的诀窍是"听起来它可以解决问题(使MySQL正确地处理UTF-8),但许多MySQL数据库默认设置为Latin1,所以这不会使它成为一个正确的解决方案。我将把默认字符集和表字符集更改为utf8mb4。实际上,这个答案相当不完整,所以我投了反对票。
找到了解决方案。按照http://technoguider.com/2015/05/utf8-set-up-in-mysql中的规定运行以下命令/
1 2 3 4 5 6
| SET NAMES UTF8 ;
set collation_server = utf8_general_ci ;
set default-character -set = utf8 ;
set init_connect = ’ SET NAMES utf8′ ;
set character_set_server = utf8 ;
set character_set_client = utf8 ; |
- 最后两行是多余的,因为第一行已经包含了:dev.mysql.com/doc/refman/5.0/en/charset-connection.html
- 也不是一个完整的解决方案。柱子需要CHARACTER SET utf8。root不会执行所有重要的init_connect。
将数据库连接设置为utf8:
1 2 3 4
| if($handle = @mysql_connect (DB_HOST , DB_USER , DB_PASS )){
//set to utf8 encoding
mysql_set_charset ('utf8',$handle );
} |
。
- 如果运行php,不要使用不推荐使用的mysql_*接口。切换到mysqli_*或PDO。