<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>字符集 on ZRJ | 学习笔记</title>
        <link>https://blog.zrj.me/tags/%E5%AD%97%E7%AC%A6%E9%9B%86/</link>
        <description>Recent content in 字符集 on ZRJ | 学习笔记</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-CN</language>
        <lastBuildDate>Tue, 27 Nov 2012 21:36:04 +0800</lastBuildDate><atom:link href="https://blog.zrj.me/tags/%E5%AD%97%E7%AC%A6%E9%9B%86/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>加深对 mysql 编码的理解</title>
        <link>https://blog.zrj.me/posts/2012-11-27-%E5%8A%A0%E6%B7%B1%E5%AF%B9-mysql-%E7%BC%96%E7%A0%81%E7%9A%84%E7%90%86%E8%A7%A3/</link>
        <pubDate>Tue, 27 Nov 2012 21:36:04 +0800</pubDate>
        
        <guid>https://blog.zrj.me/posts/2012-11-27-%E5%8A%A0%E6%B7%B1%E5%AF%B9-mysql-%E7%BC%96%E7%A0%81%E7%9A%84%E7%90%86%E8%A7%A3/</guid>
        <description>&lt;p&gt;今天在这里，&lt;a class=&#34;link&#34; href=&#34;http://www.cppblog.com/yg2362/archive/2012/11/26/195711.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://www.cppblog.com/yg2362/archive/2012/11/26/195711.html&lt;/a&gt;，看到这篇&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们举个例子，假设一个汉字的字符编码为0xFFFF，它在屏幕上能够正常显示，如果汉字存入数据库的时候和从数据库中取出的时候，编码一致，那么它肯定不是乱码。反过来，如果输出的时候是乱码，那么它肯定被转码了，至于为什么被转码了，我们得看看mysql里面做了什么(mysql难道会把无码片变成了有码片？) 首先mysql里面有2个概念，一个叫character set,一个叫collation。我们先说说character set。字符集就是数字，英文字符，汉字等编码格式，我们常见的是utf8,gbk,gb2312。mysql里面比较复杂，有4个东西跟它有关，分别是character_set_client，character_set_connection，character_set_database，character_set_results。set names (latin1)其实就是character_set_client=latin1，character_set_connection=latin1，character_set_results=latin1，它的流程是character_set_client ==&amp;gt; character_set_connection ==&amp;gt; Table Character ==&amp;gt; character_set_results。 我们按照上面的流程，来分析第一个问题。 set names &amp;rsquo;latin1&amp;rsquo;&amp;mdash;-执行了character_set_client=latin1，character_set_connection=latin1，character_set_results=latin1; insert into test_latin1 set name=&amp;lsquo;王&amp;rsquo;;这句话，mysql做了什么事呢？首先，character_set_client,它会把王字的编码当成latin1的编码传递给character_set_connection（此时不会转码），character_set_connection会把编码传递给Table Character,因为表本身是latin1，所以此时也不需要转码，select name from test_latin1;mysql会把test_latin1中的编码传递给前端，此时也不需要转码，所以，走个流程下来，我们输入的是什么编码，输出的还是相同的编码，因此，第一个问题的答案是不会是乱码。我画个流程图latin1==&amp;gt;latin1==&amp;gt;latin1==&amp;gt;latin1,没有转码的过程&lt;/p&gt;
&lt;p&gt;我们在来看第二个问题。 set names &amp;rsquo;test_gbk&amp;rsquo;&amp;mdash;-执行了character_set_client=gbk，character_set_connection=gbk，character_set_results=gbk; insert into test_latin1 set name=&amp;lsquo;王&amp;rsquo;;character_set_client,它会把王字的编码当成gbk的编码传递给character_set_connection（此时不会转码）,character_set_connection会把编码传递给Table Character,因为表是lanti1的编码格式，这个过程的时候就会进行转码，但是latin1的字符集小于gbk的字符集，所以它会找不到对应字符的编码，此时会以？代替。select name from test_latin1，此时会从latin1转码成gbk,但是此时latin1已经是错误的数据了，所以得到的gbk编码也是错误的了。流程gbk==&amp;gt;gbk==&amp;gt;latin1==&amp;gt;gbk,其中gbk==&amp;gt;latin1出了问题，我们select出来的数据也就不可能是输入时候的数据了。因此，这个问题的答案是乱码。&lt;/p&gt;
&lt;p&gt;第三个。 set names &amp;rsquo;test_latin1&amp;rsquo; insert into test_utf8 set name=&amp;lsquo;王&amp;rsquo;;character_set_client,它会把王字的编码当成latin1的编码传递给character_set_connection（此时不会转码）,character_set_connection会把编码传递给Table Character,此时表是utf8的格式，因此会进行转码，latin1==&amp;gt;utf8,因为utf8的字符集&amp;gt;latin1字符集，因此，转码正常。select name from test_utf8;会从utf8转码成latin1,此时可以转码成功，因此我们最终得到的和输入的时候是一致的，因此答案不是乱码。流程latin1==&amp;gt;latin1==&amp;gt;utf8==&amp;gt;latin1,从小的字符集到大的字符集再到小的字符集，转码是不会有问题的。 屁话了这么多，无非想告诉大家一个万精油方法，表创建的字符集和set names都设置成同一个字符集，就基本可以满足输入数据不会在转换过程中失真，也就是说输入是什么，输出就是什么。建议有中文的都设置成utf8字符集，一劳永逸。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;联想到自己将要做的一个模块，是一个爬虫的模块，在功能的实现中，遇到的问题是网页的编码是 gbk 的，但是我的数据库是 utf8 的，于是之前没事干的时候就在思考这个问题要怎么解决，当时自己想的一个方法是抓回来 gbk 的内容之后，查 php 手册看看有没有 gbk-&amp;gt;utf8 的编码转换函数，而且我相信这样的函数应该还是会有的，直到看了这篇，试了一下，文件的编码是 gbk，在开始的时候 set names gbk，然后往里插入 gbk 的中文字符，结果居然可以，看来事情容易了很多&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
