查表的时候显示某个字段乱码
# mysql -u -p -S /tmp/mysql.sock
mysql> select * from my_a limit 1\G
*************************** 1. row ***************************
id: 2
gmt_create: 2019-01-01 00:00:02
gmt_modify: 2019-03-03 21:12:36
gmt_create1: 2019-03-03 21:12:36
gmt_modify1: 2019-03-03 21:12:36
k: 279134
c: 50739423477-59896895752-91121550334-25071371310-03454727381-25307272676-12883025003-48844794346-97662793974-67443907837
pad: 10824941535-62754685647-36430831520-45812593797-70371571680
d: 279134
e: 50739423477-59896895752-91121550334-25071371310-03454727381-25307272676-12883025003-48844794346-97662793974-67443907837
pad2: ???????
??????????
1 row in set (0.00 sec)
查看当前session字符集设置
mysql> show variables like '%chara%';
+--------------------------+-------------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /home/mysql/program/mysql-5.7.22-linux-glibc2.12-x86_64/share/charsets/ |
+--------------------------+-------------------------------------------------------------------------+
8 rows in set (0.00 sec)
修改当前session的字符集设置,再查看表记录
mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%chara%';
+--------------------------+-------------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /home/mysql/program/mysql-5.7.22-linux-glibc2.12-x86_64/share/charsets/ |
+--------------------------+-------------------------------------------------------------------------+
8 rows in set (0.00 sec)
mysql> select * from my_a limit 1\G
*************************** 1. row ***************************
id: 2
gmt_create: 2019-01-01 00:00:02
gmt_modify: 2019-03-03 21:12:36
gmt_create1: 2019-03-03 21:12:36
gmt_modify1: 2019-03-03 21:12:36
k: 279134
c: 50739423477-59896895752-91121550334-25071371310-03454727381-25307272676-12883025003-48844794346-97662793974-67443907837
pad: 10824941535-62754685647-36430831520-45812593797-70371571680
d: 279134
e: 50739423477-59896895752-91121550334-25071371310-03454727381-25307272676-12883025003-48844794346-97662793974-67443907837
pad2: 你知道不???
???你这是在干嘛?
1 row in set (0.00 sec)
在客户端mysql命令行参数加上–default-character-set=utf8
mysql -u -p -S /tmp/mysql.sock --default-character-set=utf8
在mysql配置文件中加上如下内容,并在客户端mysql命令行参数加上–defaults-file=/home/mysql/conf/my1.cnf
[mysql]
default-character-set = utf8
/// mysql命令行参数
# mysql --defaults-file=/home/mysql/conf/my1.cnf -u -p
如果在mysql配置文件里的[mysql]下加了default-character-set = utf8,但如果使用mysql -u -p -S /tmp/mysql.sock不指定配置文件去连接mysql,此时显示的character_set_client、character_set_connection、character_set_results仍是latin1,那么此时的客户端mysql命令是从哪里去获取这些字符集的值的呢?
使用strace来看一下mysql命令行连接的时候的情况:
# strace -o /tmp/bbb_my.strace mysql -u -p -S /tmp/mysql.sock
查看后发现读的最后的配置文件是/etc/my.cnf.d/mysql-clients.cnf
查看/etc/my.cnf和/etc/my.cnf.d/mysql-clients.cnf中的内容
/etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
/etc/my.cnf.d/mysql-clients.cnf
#
# These groups are read by MariaDB command-line tools
# Use it for options that affect only one utility
#
[mysql]
[mysql_upgrade]
[mysqladmin]
[mysqlbinlog]
[mysqlcheck]
[mysqldump]
[mysqlimport]
[mysqlshow]
[mysqlslap]
发现配置文件中没有相应的字符集设置,所以采用的是默认的character_set_client、character_set_connection、character_set_results的字符集。默认的字符集是latin1,参考官网:
The mysql, mysqladmin, mysqlcheck, mysqlimport, and mysqlshow client programs determine the default character set to use as follows:
我们在/etc/my.cnf.d/mysql-clients.cnf文件中的[mysql]下添加default-character-set = utf8,保存后,再通过mysql -u -p -S /tmp/mysql.sock去连接,发现如下,character_set_client、character_set_connection、character_set_results已被修改为utf8。
mysql> show variables like '%chara%';
+--------------------------+-------------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /home/mysql/program/mysql-5.7.22-linux-glibc2.12-x86_64/share/charsets/ |
+--------------------------+-------------------------------------------------------------------------+
8 rows in set (0.01 sec)
其实在官网中除了上面提到的一点,还有另一点,完整的如下:
The mysql, mysqladmin, mysqlcheck, mysqlimport, and mysqlshow client programs determine the default character set to use as follows:
In the absence of other information, each client uses the compiled-in default character set, usually latin1.
Each client can autodetect which character set to use based on the operating system setting, such as the value of the LANG or LC_ALL locale environment variable on Unix systems or the code page setting on Windows systems. For systems on which the locale is available from the OS, the client uses it to set the default character set rather than using the compiled-in default. For example, setting LANG to ru_RU.KOI8-R causes the koi8r character set to be used. Thus, users can configure the locale in their environment for use by MySQL clients.
The OS character set is mapped to the closest MySQL character set if there is no exact match. If the client does not support the matching character set, it uses the compiled-in default. For example, ucs2 is not supported as a connection character set, so it maps to the compiled-in default.
也就是说mysql client会自动去识别client端os的字符集设置,比如:LANG、LC_ALL。如果locale对于os是可用的,那么mysql client就会把它作为默认的字符集,而不是使用内建的字符集。
查看系统的locale设置:
$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
进入mysql查看此时字符集
$ mysql -S /tmp/mysql.sock
mysql> show variables like '%char%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.00 sec)
修改系统的locale设置
$ export LANG='zh_CN.GBK'
$ locale
LANG=zh_CN.GBK
LC_CTYPE="zh_CN.GBK"
LC_NUMERIC="zh_CN.GBK"
LC_TIME="zh_CN.GBK"
LC_COLLATE="zh_CN.GBK"
LC_MONETARY="zh_CN.GBK"
LC_MESSAGES="zh_CN.GBK"
LC_PAPER="zh_CN.GBK"
LC_NAME="zh_CN.GBK"
LC_ADDRESS="zh_CN.GBK"
LC_TELEPHONE="zh_CN.GBK"
LC_MEASUREMENT="zh_CN.GBK"
LC_IDENTIFICATION="zh_CN.GBK"
LC_ALL=
查看此时mysql client的字符集
$ mysql -S /tmp/mysql.sock
mysql> show variables like '%char%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | gbk |
| character_set_connection | gbk |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | gbk |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.01 sec)
如果LC_CTYPE与其余参数的设置不一致,则以LC_CTYPE为准
$ locale
LANG=zh_CN.GBK
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="zh_CN.GBK"
LC_TIME="zh_CN.GBK"
LC_COLLATE="zh_CN.GBK"
LC_MONETARY="zh_CN.GBK"
LC_MESSAGES="zh_CN.GBK"
LC_PAPER="zh_CN.GBK"
LC_NAME="zh_CN.GBK"
LC_ADDRESS="zh_CN.GBK"
LC_TELEPHONE="zh_CN.GBK"
LC_MEASUREMENT="zh_CN.GBK"
LC_IDENTIFICATION="zh_CN.GBK"
LC_ALL=
mysql> show variables like '%char%';
+--------------------------+-------------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /home/mysql/program/mysql-5.7.22-linux-glibc2.12-x86_64/share/charsets/ |
+--------------------------+-------------------------------------------------------------------------+
8 rows in set (0.00 sec)
注意:如果locale和疑问一节中mysql client会读取的/etc/my.cnf.d/mysql-clients.cnf配置文件[mysql]都配置了,且不一致的话,则以mysql client会读取的配置文件为准。
如果locale显示有问题,如下。是因为系统压根就没有UTF-8这个语系,所以会报找不到。可以通过locale -a查看系统支持的语系。在这种情况下,mysql client就继承不了LC_CTYPE的character set,需要将LC_CTYPE修改成正确的值。
# locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en_US.UTF-8
LC_CTYPE=UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
# mysql -S /tmp/mysql.sock
mysql> show variables like '%char%';
+--------------------------+-------------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /home/mysql/program/mysql-5.7.22-linux-glibc2.12-x86_64/share/charsets/ |
+--------------------------+-------------------------------------------------------------------------+
8 rows in set (0.00 sec)
通过这篇文章,我们可以知道mysql client去连接mysql server的时候,关于character set的值是从哪几个地方去获取的
这里,character_set_database、character_set_filesystem、character_set_server、character_set_system的含义不加赘述,可以参考官网。
https://dev.mysql.com/doc/refman/5.7/en/charset-connection.html
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_character_set_client
https://www.cnblogs.com/JMLiu/p/8313204.html
http://www.mamicode.com/info-detail-1866747.html