美文网首页嵌牛IT观察
MYSQL 数据乱码和字符集问题

MYSQL 数据乱码和字符集问题

作者: 大猫_23fe | 来源:发表于2018-07-05 20:56 被阅读2次

    顾颖17021223250

    转载自https://blog.csdn.net/qingqing7/article/details/78465858

    【嵌牛导读】:MySQL对于字符集的指定可以细化到一个数据库,一张表,一列,应该用什么字符集。 但是,传统的程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢?

    文件系统字符集是固定的,系统、服务器的字符集在安装时确定,与乱码问题无关;乱码的问题与客户端、数据库连接、数据库、查询结果的字符集设置有关。

    【嵌牛鼻子】:MySQL字符集 中文乱码

    【嵌牛提问】:MySQL语句都有什么?如何使用mysql语句操作mysql?

    【嵌牛正文】:

    1、MySQL的字符集问题

    关于MySQL的字符集问题更详细可参考

    MySQL的字符集支持(Character Set Support)有两个方面:

    字符集(Character set)和排序方式(Collation)。

    对于字符集的支持细化到四个层次:

    服务器(server),数据库(database),数据表(table)和连接(connection)。

    1.1、MySQL默认字符集

    MySQL对于字符集的指定可以细化到一个数据库,一张表,一列,应该用什么字符集。

    但是,传统的程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢?

    (1)编译MySQL 时,指定了一个默认的字符集,这个字符集是 latin1;

    (2)安装MySQL 时,可以在配置文件 (my.cnf) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的;

    (3)启动mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的配置,此时 character_set_server 被设定为这个默认的字符集;

    (4)当创建一个新的数据库时,除非明确指定,这个数据库的字符集被缺省设定为character_set_server;

    (5)当选定了一个数据库时,character_set_database 被设定为这个数据库默认的字符集;

    (6)在这个数据库里创建一张表时,表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集;

    (7)当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集;

    简单的总结一下,如果什么地方都不修改,那么所有的数据库的所有表的所有栏位的都用

    latin1存储,不过我们如果安装 MySQL,一般都会选择多语言支持,也就是说,安装程序会自动在配置文件中把

    default_character_set设置为 UTF-8,这保证了缺省情况下,所有的数据库的所有表的所有栏位的都用 UTF-8 存储。

    1.2、查看默认字符集

    (默认情况下,mysql的字符集是latin1(ISO_8859_1)

    通常,查看系统的字符集和排序方式的设定可以通过下面的两条命令:

    show variables like 'character%';

    结果如下:

    +--------------------------+----------------------------+

    | Variable_name            | Value                      |

    +--------------------------+----------------------------+

    | character_set_client     | utf8                       |

    | character_set_connection | utf8                       |

    | character_set_database   | latin1                     |

    | character_set_filesystem | binary                     |

    | character_set_results    | utf8                       |

    | character_set_server     | latin1                     |

    | character_set_system     | utf8                       |

    | character_sets_dir       | /usr/share/mysql/charsets/ |

    +--------------------------+----------------------------+

    show variables like 'collation%'

    结果如下:

    +----------------------+-------------------+

    | Variable_name        | Value             |

    +----------------------+-------------------+

    | collation_connection | utf8_general_ci   |

    | collation_database   | latin1_swedish_ci |

    | collation_server     | latin1_swedish_ci |

    +----------------------+-------------------+

    MySQL中涉及的几个字符集解释:

    character_set_server/default_character_set:服务器字符集,默认情况下所采用的。

    character_set_database:数据库字符集。

    character_set_table:数据库表字符集。

    优先级依次增加。所以一般情况下只需要设置character_set_server,而在创建数据库和表时不特别指定字符集,这样统一采用character_set_server字符集。

    character_set_client:客户端的字符集。客户端默认字符集。当客户端向服务器发送请求时,请求以该字符集进行编码。

    character_set_results:结果字符集。服务器向客户端返回结果或者信息时,结果以该字符集进行编码。

    在客户端,如果没有定义character_set_results,则采用character_set_client字符集作为默认的字符集。所以只需要设置character_set_client字符集。

    要处理中文,则可以将character_set_server和character_set_client均设置为GB2312,如果要同时处理多国语言,则设置为UTF8。

    1.3、修改默认字符集

    (1)最简单的修改方法,就是修改mysql的my.cnf文件中的字符集键值,一般情况下my.cnfd在/etc文件夹下。如果没有可以自己创建该文件。并添加如下内容:(还没验证)

    default_character_set = utf8

    character_set_server = utf8

    修改完后,重启mysql的服务,service mysql restart

    使用mysql> SHOW VARIABLES LIKE 'character%';查看,发现数据库编码均已改成utf8

    (2)还有一种修改字符集的方法,就是使用mysql的命令

    在登录数据库时,我们用mysql --default-character-set=字符集-u root -p进行连接,这时我们再用show variables like '%char%';命令查看字符集设置情况,可以发现客户端、数据库连接、查询结果的字符集已经设置成登录时选择的字符集了;

    如果是已经登录了,可以使用set names字符集;命令来实现上述效果,等同于下面的命令:

    mysql> set character_set_client=utf8;

    mysql> set character_set_connection=utf8;

    mysql> set character_set_database=utf8;

    mysql> set character_set_results=utf8;

    mysql> set character_set_server=utf8;

    mysql> set character_set_system=utf8;

    mysql> set collation_connection=utf8;

    mysql> set collation_database=utf8;

    mysql> set collation_server=utf8;

    (3)其他的一些设置方法:

    修改数据库的字符集

    mysql>use mydb

    mysql>alter database mydb character set utf-8;

    创建数据库指定数据库的字符集

    mysql>create database mydb character set utf-8;

    2、mysql中文乱码问题

    解决乱码的方法是,在执行SQL语句之前,将MySQL以下三个系统参数设置为与服务器字符集character-set-server相同的字符集。

    character_set_client:客户端的字符集。

    character_set_results:结果字符集。

    character_set_connection:连接字符集。

    关于编码格式GBK、GB2312、UTF8

    UTF- 8:Unicode Transformation Format-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。

    GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。

    GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:

    GBK、GB2312--Unicode--UTF8

    UTF8--Unicode--GBK、GB2312

    对于一个网站、论坛来说,如果英文字符较多,则建议使用UTF-8节省空间。不过现在很多论坛的插件一般只支持GBK。

    GB2312是GBK的子集,GBK是GB18030的子集

    GBK是包括中日韩字符的大字符集合

    如果是中文的网站推荐GB2312 GBK有时还是有点问题

    为了避免所有乱码问题,应该采用UTF-8,将来要支持国际化也非常方便

    UTF-8可以看作是大字符集,它包含了大部分文字的编码。

    使用UTF-8的一个好处是其他地区的用户(如香港台湾)无需安装简体中文支持就能正常观看你的文字而不会出现乱码。

    gb2312是简体中文的码

    gbk支持简体中文及繁体中文

    big5支持繁体中文

    utf-8支持几乎所有字符

    2.1、解决方法

    首先分析乱码的情况

    1.写入数据库时作为乱码写入

    2.查询结果以乱码返回

    究竟在发生乱码时是哪一种情况呢?

    我们先在mysql命令行下输入

    show variables like‘%char%’;

    查看mysql字符集设置情况:

    文件系统字符集是固定的,系统、服务器的字符集在安装时确定,与乱码问题无关;乱码的问题与客户端、数据库连接、数据库、查询结果的字符集设置有关。

    *注:客户端是看访问mysql 数据库的方式,通过命令行访问,命令行窗口就是客户端,通过JDBC 等连接访问,程序就是客户端。

    我们在向mysql写入中文数据时,在客户端、数据库连接、写入数据库时分别要进行编码转换在执行查询时,在返回结果、数据库连接、客户端分别进行编码转换。现在我们应该清楚,乱码发生在数据库、客户端、查询结果以及数据库连接这其中一个或多个环节。

    为什么从命令行直接写入中文不设置也不会出现乱码?

    可以明确的是从命令行下,客户端、数据库连接、查询结果的字符集设置没有变化输入的中文经过一系列转码又转回初始的字符集,我们查看到的当然不是乱码但这并不代表中文在数据库里被正确作为中文字符存储举例来说,现在有一个utf8编码数据库,客户端连接使用GBK 编码,connection 使用默认的ISO8859-1(也就是mysql 中的latin1),我们在客户端发送“中文”这个字符串,客户端将发送一串GBK 格式的二进制码给connection 层,connection 层以ISO8859-1 格式将这段二进制码发送给数据库,数据库将这段编码以utf8 格式存储下来,我们将这个字段以utf8格式读取出来,肯定是得到乱码,也就是说中文数据在写入数据库时是以乱码形式存储的,在同一个客户端进行查询操作时,做了一套和写入时相反的操作,错误的utf8 格式二进制码又被转换成正确的GBK 码并正确显示出来。

    我们可以通过之前讲的方法来设置相应的字符集。通过这样的设置,整个数据写入读出流程中都统一了字符集,就不会出现乱码了。

    如果是通过JDBC连接数据库,可以这样写URL:

    URL=jdbc:mysql://localhost:3306/abs?useUnicode=true&characterEncoding=字符集,JSP 页面等终端也要设置相应的字符集。

    2.2、R连接mysql乱码问题

    在R读入mysql数据库出现中文乱码,首先确保mysql数据库中字符集编码格式为utf-8;然后在本地电脑上(windows系统)的数据源设置中(控制面板–管理工具–数据源–配置–detail)设置好对应mysql数据库连接的字符集编码为utf-8,然后在R中channel_temp=odbcConnect(“数据库连接的名称”,uid =”xx” ,pwd =”xx”,DBMSencoding=”UTF-8”),指定编码,则不会出现乱码。

    mysq NULL值替换

    将mysql数据库中的NULL值替换为空

    UPDATE qrt_order_info SET order_num=” WHERE order_num=”NULL”;

    原本在数据库的NULL是被当成字符串了,不同的语言,表示空的方法都不一样,mysql中是”\N”;所有可以在加载数据前,对NULL作替换,这样一次性导入后就自动为空,而不需要像上面那样去数据库里UPDATE了。

    mysql内NULL判断的是空,就是没有任何值,此时用navicat查看的时候可以看淡灰色的”(Null)”字样;有时会在数据库记录的某一栏看不到任务记录,此时未必是NULL,有可能是空字符,”,只不过字符串里没任何内容,此时要用where xx=”;

    相关文章

      网友评论

        本文标题:MYSQL 数据乱码和字符集问题

        本文链接:https://www.haomeiwen.com/subject/uwlmuftx.html