Mysql 字符集(學(xué)習(xí)筆記十)

show charcater set;

show variables like '%character%';

1.查看mysql所支持的字符集

指令:SHOW CHARACTER SET;

很多很多匣距,這里就不全部放上來了,這里的charset代表字符集,就是編碼對應(yīng)字符的集合,后面的collation代表了字符序,字符序就是每種不同的字符集在比較時采用的不同的方法溉仑。只要表上有的字符集,就可以被我們采用。

2.當(dāng)前關(guān)于mysql的各種字符集

指令:SHOW VARIABLES LIKE ‘character%’;

這張圖是經(jīng)過我更改my.ini配置后的各個項目的字符集鳖链,我都改成了utf8,因為utf8支持漢字墩莫,幾乎成了目前Web開發(fā)界的標(biāo)準(zhǔn)字符集芙委。下面我來解釋下各個項代表的含義。

character_set_client: 代表客戶端字符集狂秦,客戶端最簡單的來說灌侣,就是之這個命令行,或者其它操作數(shù)據(jù)庫的網(wǎng)頁裂问,應(yīng)用等等侧啼,客戶端字符集就代表了用戶輸入的字符,用什么字符集來編碼堪簿。

character_set_connection: 代表與服務(wù)器連接層的字符集痊乾,mysql是連接mysqld服務(wù)器的客戶端,兩者連接層椭更,采用的字符集哪审。

character_set_database: 數(shù)據(jù)庫采用的字符集。

character_set_filesystem: 文件采用的肯定是二進制最合適虑瀑,不用修改湿滓。

character_set_result: 結(jié)果字符集,返回結(jié)果時采用的字符集舌狗。

character_set_server: mysql服務(wù)器采用的字符集叽奥,也就是操作默認的字符集。

character_set_system: 系統(tǒng)字符集把夸,比如我們輸入的命令'insert ...'這些語句字符串采用的字符集而线。

有一點很重要:在創(chuàng)建時未設(shè)置字符集的情況下,當(dāng)前創(chuàng)建的東西會根據(jù)上一級的字符集來確定字符集恋日,比如創(chuàng)建數(shù)據(jù)庫未指定字符集膀篮,則會采用server的字符集來作為庫的字符集,創(chuàng)建數(shù)據(jù)表時為指定字符集岂膳,則會采用數(shù)據(jù)庫的字符集來作為庫的字符集誓竿。以此類推,從下到上為 記錄<表<庫<服務(wù)器谈截。

舉個例子:

創(chuàng)建一個為指定字符集的數(shù)據(jù)庫

3.更改my.ini配置文件來更改默認字符集

[mysql]

default-character-set=utf8

[mysqld]

character_set_client=utf8

character_set_server=utf8

collation_server=utf8_bin

4.在創(chuàng)建時指定字符集

除了采用默認的字符集外筷屡,還可以在創(chuàng)建時設(shè)置字符集涧偷,但是要清楚是為哪個設(shè)置字符集。

如圖毙死,在創(chuàng)建數(shù)據(jù)表時指定字符集:

指令:CREATE DATABASE db2 character set gbk;

不管創(chuàng)建什么燎潮,后面加一句character set <字符集>; ?這樣就可以指定了。

當(dāng)然還可以更改一個數(shù)據(jù)表的字符集:alter table tbname convert to charset gbk;



MySQL字符集詳解

一扼倘、字符集和校驗規(guī)則

字符集是一套符合和編碼确封,校驗規(guī)則(collation)是在字符集內(nèi)用于比較字符的一套規(guī)則,即字符集的排序規(guī)則再菊。MySQL可以使用對種字符集和檢驗規(guī)則來組織字符爪喘。

MySQL服務(wù)器可以支持多種字符集,在同一臺服務(wù)器纠拔,同一個數(shù)據(jù)庫秉剑,甚至同一個表的不同字段都可以指定使用不同的字符集,相比oracle等其他數(shù)據(jù)庫管理系統(tǒng)稠诲,在同一個數(shù)據(jù)庫只能使用相同的字符集侦鹏,MySQL明顯存在更大的靈活性。

每種字符集都可能有多種校對規(guī)則吕粹,并且都有一個默認的校對規(guī)則种柑,并且每個校對規(guī)則只是針對某個字符集,和其他的字符集么有關(guān)系匹耕。

在MySQL中聚请,字符集的概念和編碼方案被看做是同義詞,一個字符集是一個轉(zhuǎn)換表和一個編碼方案的組合稳其。

Unicode(Universal Code)是一種在計算機上使用的字符編碼驶赏。Unicode 是為了解決傳統(tǒng)的字符編碼方案的局限而產(chǎn)生的,它為每種語言中的每個字符設(shè)定了統(tǒng)一并且唯一的二進制編碼既鞠,以滿足跨語言煤傍、跨平臺進行文本轉(zhuǎn)換、處理的要求嘱蛋。Unicode存在不同的編碼方案蚯姆,包括Utf-8,Utf-16和Utf-32洒敏。Utf表示Unicode Transformation Format龄恋。

二、查看mysql字符集方法

1凶伙、查看mysql服務(wù)器支持的字符集

mysql> show character set;

mysql> select * from information_schema.character_sets;

mysql> select character_set_name, default_collate_name, description, maxlen from

information_schema.character_sets;

2郭毕、查看字符集的校對規(guī)則

mysql> show collation;

mysql> show collation like 'utf8';

mysql> select * from information_schema.collations where collation_name like 'utf8%';

3、查看當(dāng)前數(shù)據(jù)庫的字符集

mysql> show variables like 'character%';

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

| Variable_name | Value |

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

| character_set_client | utf8 |

| character_set_connection | utf8 |

| character_set_database | latin1 |

| character_set_filesystem | utf8 |

| 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)

名詞解釋:

character_set_client:客戶端請求數(shù)據(jù)的字符集

character_set_connection:客戶機/服務(wù)器連接的字符集

character_set_database:默認數(shù)據(jù)庫的字符集函荣,無論默認數(shù)據(jù)庫如何改變显押,都是這個字符集扳肛;如果沒有默認數(shù)據(jù)庫,那就使用 character_set_server指定的字符集乘碑,這個變量建議由系統(tǒng)自己管理挖息,不要人為定義。

character_set_filesystem:把os上文件名轉(zhuǎn)化成此字符集蝉仇,即把 character_set_client轉(zhuǎn)換character_set_filesystem旋讹, 默認binary是不做任何轉(zhuǎn)換的

character_set_results:結(jié)果集殖蚕,返回給客戶端的字符集

character_set_server:數(shù)據(jù)庫服務(wù)器的默認字符集

character_set_system:系統(tǒng)字符集轿衔,這個值總是utf8,不需要設(shè)置睦疫。這個字符集用于數(shù)據(jù)庫對象(如表和列)的名字害驹,也用于存儲在目錄表中的函數(shù)的名字。

4蛤育、查看當(dāng)前數(shù)據(jù)庫的校對規(guī)則

mysql> show variables like 'collation%';

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

| Variable_name | Value |

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

| collation_connection | utf8_general_ci |

| collation_database | latin1_swedish_ci |

| collation_server | utf8_general_ci |

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

3 rows in set (0.01 sec)

名詞解釋:

collation_connection 當(dāng)前連接的字符集宛官。

collation_database??? 當(dāng)前日期的默認校對。每次用USE語句來“跳轉(zhuǎn)”到另一個數(shù)據(jù)庫的時候瓦糕,這個變量的值就會改變底洗。如果沒有當(dāng)前數(shù)據(jù)庫,這個變量的值就是collation_server變量的值咕娄。

collation_server 服務(wù)器的默認校對亥揖。

排序方式的命名規(guī)則為:字符集名字_語言_后綴,其中各個典型后綴的含義如下:

1)_ci:不區(qū)分大小寫的排序方式

2)_cs:區(qū)分大小寫的排序方式

3)_bin:二進制排序方式圣勒,大小比較將根據(jù)字符編碼费变,不涉及人類語言,因此_bin的排序方式不包含人類語言

三圣贸、MySQL字符集的設(shè)置

1挚歧、概述

MySQL字符集設(shè)置分為兩類:

1)創(chuàng)建對象的默認值。

2)控制server和client端交互通信的配置吁峻。

1滑负、創(chuàng)建對象的默認值

字符集合校對規(guī)則有4個級別的默認設(shè)置:

1)服務(wù)器級別;

2)數(shù)據(jù)庫級別用含;

3)表級別矮慕、列級別;

4)連接級別耕餐。

更低級別的設(shè)置會集成高級別的設(shè)置凡傅。

這里有一個通用的規(guī)則:先為服務(wù)器或者數(shù)據(jù)庫選擇一個合理的字符集,然后根據(jù)不同的實際情況肠缔,讓某個列選擇自己的字符集夏跷。

2哼转、控制server和client端交互通信的配置

大部分MySQL客戶端都不具備同時支持多種字符集的能力,每次都只能使用一種字符集槽华。

客戶和服務(wù)器之間的字符集轉(zhuǎn)換工作是由如下幾個MySQL系統(tǒng)變量控制的壹蔓。

1)character_set_server:mysql server默認字符集。

2)character_set_database:數(shù)據(jù)庫默認字符集猫态。

3)character_set_client:MySQL server假定客戶端發(fā)送的查詢使用的字符集佣蓉。

4)character_set_connection:MySQL Server接收客戶端發(fā)布的查詢請求后,將其轉(zhuǎn)換為character_set_connection變量指定的字符集亲雪。

5)character_set_results:mysql server把結(jié)果集和錯誤信息轉(zhuǎn)換為character_set_results指定的字符集勇凭,并發(fā)送給客戶端。

6)character_set_system:系統(tǒng)元數(shù)據(jù)(字段名等)字符集

還有以collation_開頭的同上面對應(yīng)的變量义辕,用來描述字符序虾标。

注意事項:

? my.cnf中的default_character_set設(shè)置只影響mysql命令連接服務(wù)器時的連接字符集,不會對使用libmysqlclient庫的應(yīng)用程序產(chǎn)生任何作用灌砖!

? 對字段進行的SQL函數(shù)操作通常都是以內(nèi)部操作字符集進行的璧函,不受連接字符集設(shè)置的影響。

? SQL語句中的裸字符串會受到連接字符集或introducer設(shè)置的影響基显,對于比較之類的操作可能產(chǎn)生完全不同的結(jié)果蘸吓,需要小心!

3撩幽、默認情況下字符集選擇規(guī)則

(1)編譯MySQL 時库继,指定了一個默認的字符集,這個字符集是 latin1;

(2)安裝MySQL 時摸航,可以在配置文件 (my.cnf) 中指定一個默認的的字符集制跟,如果沒指定,這個值繼承自編譯時指定的;

(3)啟動mysqld 時酱虎,可以在命令行參數(shù)中指定一個默認的的字符集雨膨,如果沒指定,這個值繼承自配置文件中的配置,此時character_set_server被設(shè)定為這個默認的字符集;

(4)當(dāng)創(chuàng)建一個新的數(shù)據(jù)庫時读串,除非明確指定聊记,這個數(shù)據(jù)庫的字符集被缺省設(shè)定為character_set_server;

(5)當(dāng)選定了一個數(shù)據(jù)庫時,character_set_database被設(shè)定為這個數(shù)據(jù)庫默認的字符集;

(6)在這個數(shù)據(jù)庫里創(chuàng)建一張表時恢暖,表默認的字符集被設(shè)定為character_set_database排监,也就是這個數(shù)據(jù)庫默認的字符集;

(7)當(dāng)在表內(nèi)設(shè)置一欄時,除非明確指定杰捂,否則此欄缺省的字符集就是表默認的字符集;

2舆床、分述

2.1、為列分配字符集

屬于同一個表的不同列可以有不同的字符集,如果沒有為一個列顯示的定義字符集就使用默認字符集挨队。創(chuàng)建一個表的時候谷暮,若顯示的為列指定字符集,則字符集作為數(shù)據(jù)類型選項包含在其中盛垦,要放在數(shù)據(jù)類型后面及空指定和主鍵前面湿弦。

例如:

create table column_charset(

c1 char(10) character set utf8 not null,

c2 char(10) char set utf8,

c3 varchar(10) charset utf8,

c4 varchar(10)) engine=innodb;

注意:character set可以簡寫為char setcharset

使用show create table table_name;命令查看column_charset建表語句:

mysql> show create table column_charset\G;

*************************** 1. row ***************************

Table: column_charset

Create Table: CREATE TABLE `column_charset` (

`c1` char(10) CHARACTER SET utf8 NOT NULL,

`c2` char(10) CHARACTER SET utf8 DEFAULT NULL,

`c3` varchar(10) CHARACTER SET utf8 DEFAULT NULL,

`c4` varchar(10) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1

1 row in set (0.01 sec)

ERROR:

No query specified

插入數(shù)據(jù),感受一下效果:

mysql> insert into column_charset(c1,c2,c3,c4) value("圖靈","圖靈","圖靈","chavin");

Query OK, 1 row affected (0.01 sec)

mysql> select * from column_charset;

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

| c1 | c2 | c3 | c4 |

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

| 圖靈 | 圖靈 | 圖靈 | chavin |

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

1 row in set (0.00 sec)

2.2腾夯、為表分配字符集

create table table_charset(

c1 varchar(10),

c2 varchar(10))engine=innodb default charset=utf8;

注意:為表指定字符集可以使用以下幾種方式:

default charset=utf8;

charset=utf8;

default character set=utf8;

character set=utf8;

default char set=utf8;

char set=utf8;

檢查建表語句:

mysql> show create table table_charset\G;

*************************** 1. row ***************************

Table: table_charset

Create Table: CREATE TABLE `table_charset` (

`c1` varchar(10) DEFAULT NULL,

`c2` varchar(10) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

測試:

mysql> insert into table_charset(c1,c2) values('圖靈','圖靈');

Query OK, 1 row affected (0.01 sec)

mysql> select * from table_charset;

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

| c1 | c2 |

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

| 圖靈 | 圖靈 |

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

1 row in set (0.00 sec)

2.3颊埃、為數(shù)據(jù)庫指定字符集

創(chuàng)建的每個數(shù)據(jù)庫都有一個默認字符集,如果沒有指定蝶俱,就用latin1班利。

create database dbking charset=utf8;

注意:創(chuàng)建數(shù)據(jù)庫分配字符集可以采用以下幾種子句:

charset=utf8;

default charset=utf8;

charset utf8;

default charset utf8;

char set=utf8;

default char set=utf8;

char set utf8;

default char set utf8;

character set=utf8;

default character set=utf8;

character set utf8;

default character set utf8;

使用show create database db_name;命令查看數(shù)據(jù)庫創(chuàng)建語句:

mysql> show create database dbking;

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

| Database | Create Database |

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

| dbking | CREATE DATABASE `dbking` /*!40100 DEFAULT CHARACTER SET utf8 */ |

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

1 row in set (0.00 sec)

2.4、為列分配校對規(guī)則

每個列都應(yīng)該有一個校對跷乐,如果沒有顯示指定肥败,MySQL就使用屬于該字符集的默認校對。如果指定了一個字符集和一個校對愕提,字符集應(yīng)該放在前面。

create table column_collate(

c1 varchar(10) charset utf8 collate utf8_romanian_ci not null,

c2 varchar(10) charset utf8 collate?utf8_spanish_ci)engine=innodb;

查看表的校驗規(guī)則信息:

mysql> select table_name,column_name,collation_name

from information_schema.columns

where table_name='column_collate';

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

| table_name | column_name | collation_name |

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

| column_collate | c1 | utf8_romanian_ci |

| column_collate | c2 | utf8_spanish_ci |

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

2 rows in set (0.04 sec)

注意:字符集和校對在處理字符表達式的過程中扮演著重要角色皿哨。我們不能比較兩個屬于不同校對的不同字符值浅侨。例如:

mysql> insert into column_collate(c1,c2) values('A','A');

Query OK, 1 row affected (0.22 sec)

mysql> select * from column_collate;

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

| c1 | c2 |

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

| A | A |

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

1 row in set (0.00 sec)

mysql> select * from column_collate where c1=c2;

ERROR 1267 (HY000): Illegal mix of collations (utf8_romanian_ci,IMPLICIT) and (utf8_spanish_ci,IMPLICIT) for operation '='

2.5、為表指定校對規(guī)則

create table table_collate(

c1 varchar(10),

c2 varchar(10))engine=innodb default charset utf8 collate utf8_romanian_ci;

檢查表的校對規(guī)則:

mysql> select table_name,column_name,collation_name from information_schema.columns where table_name='table_collate';

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

| table_name | column_name | collation_name |

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

| table_collate | c1 | utf8_romanian_ci |

| table_collate | c2 | utf8_romanian_ci |

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

2 rows in set (0.00 sec)

2.6证膨、為數(shù)據(jù)庫指定校對規(guī)則

create database dbking102 default charset utf8 collate utf8_romanian_ci;

查看數(shù)據(jù)庫定義語句:

mysql> show create database dbking102\G;

*************************** 1. row ***************************

Database: dbking102

Create Database: CREATE DATABASE `dbking102` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_romanian_ci */

1 row in set (0.00 sec)

2.7如输、字符直接量字符集

如果沒有顯示指定,那么字符直接量的字符集就是數(shù)據(jù)庫的默認字符集央勒。如果要顯示分配另一個字符集不见,需要把字符集的名字放在直接量前面,并且要在字符集前面加上下劃線崔步。

mysql> select _utf8'語言 Language 言語 язык';

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

| 語言 Language 言語 язык???? |

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

| 語言 Language 言語 язык???? |

+---------------------------------+??

2.8稳吮、修改和設(shè)置MySQL服務(wù)器級別字符集

MySQL服務(wù)器支持眾多不同的字符集,這類字符集可在編譯時和運行時指定井濒。

??? 1) 編譯時指定

編譯時可指定默認字符集和默認校對規(guī)則灶似,要想同時更改默認字符集和校對規(guī)則,要同時使用--with-charset和--with-collation選項瑞你。校對規(guī)則必須是字符集的合法校對規(guī)則酪惭。

./configure -- with-charset=CHARSET --with-collation=COLLATION

通過configure選項--with-extra-charsets=LIST,可以定義在服務(wù)器中再定義增加字符集者甲。LIST 指下面任何一項:

a.空格間隔的一系列字符集名

b.complex -春感,以包括不能動態(tài)裝載的所有字符集

c.all –,以將所有字符集包括進二進制

./configure -- with-charset=CHARSET --with-collation=COLLATION --with-extra-charsets=all

??? 2) 在參數(shù)文件my.cnf中指定

[mysqld]

character_set_server=utf8

??? --影響參數(shù):character_set_server 和 character_set_database

??? --注意:修改后要重啟數(shù)據(jù)庫才能生效。

[client]

default-character-set=utf8

??? --影響參數(shù):character_set_client鲫懒,character_set_connection 和character_set_results纺铭。

--注意:修改后無需重啟數(shù)據(jù)庫。

3) 在啟動參數(shù)前指定

./mysqld --character-set-server=utf8 &

--影響參數(shù):character_set_server 和 character_set_database

4)在mysql客戶端登陸時通過--default-character-set指定

mysql -uroot -pmysql?--default-character-set=utf8

--影響參數(shù):set character_set_client刀疙,set character_set_connection舶赔,set character_set_results。

??? 5)臨時指定

a)分別指定

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;

b)mysql客戶端使用:set names utf8;

等同于

set character_set_client=utf8;

set character_set_connection=utf8;

set character_set_results=utf8;

c)set character set utf8;

等同于

set character_set_client=utf8;

set character_set_results=utf8;

set collation_connection=@@collation_database;

3谦秧、總結(jié)

下面介紹下幾個MYSQL命令:

1)show character set;或show char set;

查看數(shù)據(jù)庫支持的所有字符集

2)status;或\s;

查看當(dāng)前狀態(tài) 里面包括當(dāng)然的字符集設(shè)置

3)show variables like 'char%';

查看系統(tǒng)字符集設(shè)置竟纳,包括所有的字符集設(shè)置

4)show table status from sqlstudy like '%countries%';

查看sqlstudy數(shù)據(jù)庫中表的字符集設(shè)置

5)show full columns from countries;

查看表列的字符集設(shè)置,關(guān)鍵是在同一個表中疚鲤,每列可以設(shè)置成不同的字符集

知道怎么查看字符集了锥累,下面我來說下如何設(shè)置這些字符集

1.修改服務(wù)器級

a. 臨時更改:

mysql>SET GLOBAL character_set_server=utf8;

b. 永久更改:

修改my.cnf文件

[mysqld]

character-set-server=utf8

2.修改數(shù)據(jù)庫級

a. 臨時更改:

mysql>SET GLOBAL character_set_database=utf8;

b. 永久更改:

改了服務(wù)器級就可以了

3.修改表級

mysql>ALTER TABLE table_name DEFAULT CHARSET utf8;

更改了后永久生效

4.修改列級

修改示例:

mysql>alter table `products` change `products_model` `products_model` varchar( 20 )

character set? utf8 collate utf8_general_ci null default null;

更改了后永久生效

5.更改連接字符集

a. 臨時更改:

mysql> set names utf8;

b. 永久更改:

修改my.cnf文件

在[client]中增加:

default-character-set=utf8

執(zhí)行SQL語句時信息的路徑是這樣的

信息輸入路徑:client→connection→server;

信息輸出路徑:server→connection→results.

四、MySQL數(shù)據(jù)庫中字符集轉(zhuǎn)換流程

1集歇、MySQL Server收到請求時將請求數(shù)據(jù)從character_set_client轉(zhuǎn)換為character_set_connection桶略;

2、進行內(nèi)部操作前將請求數(shù)據(jù)從character_set_connection轉(zhuǎn)換為內(nèi)部操作字符集诲宇,其確定方法如下:

使用每個數(shù)據(jù)字段的CHARACTER SET設(shè)定值际歼;

若上述值不存在,則使用對應(yīng)數(shù)據(jù)表的DEFAULT CHARACTER SET設(shè)定值(MySQL擴展姑蓝,非SQL標(biāo)準(zhǔn))鹅心;

若上述值不存在,則使用對應(yīng)數(shù)據(jù)庫的DEFAULT CHARACTER SET設(shè)定值纺荧;

若上述值不存在旭愧,則使用character_set_server設(shè)定值。

3宙暇、將操作結(jié)果從內(nèi)部操作字符集轉(zhuǎn)換為character_set_results输枯。

下圖源自于《高性能MySQL》中關(guān)于字符集轉(zhuǎn)換的圖解:

五、MySQL數(shù)據(jù)庫亂碼原因解析及案例

1占贫、產(chǎn)生亂碼的根本原因

1)客戶機沒有正確地設(shè)置client字符集桃熄,導(dǎo)致原先的SQL語句被轉(zhuǎn)換成connection所指字符集,而這種轉(zhuǎn)換靶剑,是會丟失信息的蜻拨,如果client是utf8格式,那么如果轉(zhuǎn)換成gb2312格式桩引,這其中必定會丟失信息缎讼,反之則不會丟失。一定要保證connection的字符集大于client字符集才能保證轉(zhuǎn)換不丟失信息坑匠。

2)數(shù)據(jù)庫字體沒有設(shè)置正確血崭,如果數(shù)據(jù)庫字體設(shè)置不正確,那么connection字符集轉(zhuǎn)換成database字符集照樣丟失編碼,原因跟上面一樣夹纫。

2咽瓷、亂碼或數(shù)據(jù)丟失

character_set_client:我們要告訴服務(wù)器,我給你發(fā)送的數(shù)據(jù)是什么編碼舰讹?

character_set_connection:告訴字符集轉(zhuǎn)換器茅姜,轉(zhuǎn)換成什么編碼?

character_set_results:查詢的結(jié)果用什么編碼月匣?

如果以上三者都為字符集N,可簡寫為set names 'N';

2.1 亂碼問題

模擬情景1:

向默認字符集為utf8的數(shù)據(jù)表插入utf8編碼的數(shù)據(jù)前連接字符集設(shè)置為latin1钻洒,查詢時設(shè)置連接字符集為utf8。

插入時根據(jù)MySQL服務(wù)器的默認設(shè)置锄开,character_set_client素标、character_set_connection和character_set_results均為latin1;

插入操作的數(shù)據(jù)將經(jīng)過latin1=>latin1=>utf8的字符集轉(zhuǎn)換過程萍悴,這一過程中每個插入的漢字都會從原始的3個字節(jié)變成6個字節(jié)保存头遭;

查詢時的結(jié)果將經(jīng)過utf8=>utf8的字符集轉(zhuǎn)換過程,將保存的6個字節(jié)原封不動返回癣诱,產(chǎn)生亂碼……

例如:

mysql> set names latin1;

mysql> create table temp(name varchar(10)) charset utf8;

mysql> insert into temp values('中國');

mysql> select * from temp;

+--------+

| name |

+--------+

| 中國 |

+--------+

mysql> set names utf8;

mysql> select * from temp;

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

| name |

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

| ??-??? |

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

注意:存儲字符集編碼比插入時字符集大時计维,如果原封不動返回數(shù)據(jù)會出現(xiàn)亂碼,不過可通過修改查詢字符集狡刘,避免亂碼享潜,即不會丟失數(shù)據(jù)。

2.2 數(shù)據(jù)丟失問題

模擬情景1:

向默認字符集為latin1的數(shù)據(jù)表插入utf8編碼的數(shù)據(jù)前設(shè)置了連接字符集為utf8

插入時根據(jù)連接字符集設(shè)置嗅蔬,character_set_client、character_set_connection和character_set_results均為utf8疾就;

插入數(shù)據(jù)將經(jīng)過utf8=>utf8=>latin1的字符集轉(zhuǎn)換澜术,若原始數(shù)據(jù)中含有\(zhòng)u0000~\u00ff范圍以外的Unicode字 符,會因為無法在latin1字符集中表示而被轉(zhuǎn)換為“?”(0×3F)符號猬腰,以后查詢時不管連接字符集設(shè)置如何都無法恢復(fù)其內(nèi)容了鸟废。

例如:

mysql> set names utf8;

mysql> create table temp(name varchar(10)) charset latin1;

mysql> insert into temp values('中國');

mysql> select * from temp;

+------+

| name |

+------+

| ?? |

+------+

mysql> set names latin1;

mysql> select * from temp;

+------+

| name |

+------+

| ?? |

+------+

數(shù)據(jù)不完整了,且無法恢復(fù)姑荷。

3盒延、 亂碼終極解決方案

1)首先要明確你的客戶端時候何種編碼格式,這是最重要的(IE6一般用utf8鼠冕,命令行一般是gbk添寺,一般程序是gb2312)

2)確保你的數(shù)據(jù)庫使用utf8格式,很簡單懈费,所有編碼通吃计露。

3)一定要保證connection字符集大于等于client字符集,不然就會信息丟失,比如: latin1 < gb2312 < gbk < utf8票罐,若設(shè)置set character_set_client = gb2312叉趣,那么至少connection的字符集要大于等于gb2312,否則就會丟失信息

4)以上三步做正確的話该押,那么所有中文都被正確地轉(zhuǎn)換成utf8格式存儲進了數(shù)據(jù)庫疗杉,為了適應(yīng)不同的瀏覽器,不同的客戶端蚕礼,你可以修改character_set_results來以不同的編碼顯示中文字體烟具,由于utf8是大方向,因此web應(yīng)用是我還是傾向于使用utf8格式顯示中文的闻牡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末净赴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子罩润,更是在濱河造成了極大的恐慌玖翅,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件割以,死亡現(xiàn)場離奇詭異金度,居然都是意外死亡,警方通過查閱死者的電腦和手機严沥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門猜极,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人消玄,你說我怎么就攤上這事跟伏。” “怎么了翩瓜?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵受扳,是天一觀的道長。 經(jīng)常有香客問我兔跌,道長勘高,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任坟桅,我火速辦了婚禮华望,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仅乓。我一直安慰自己赖舟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布方灾。 她就那樣靜靜地躺著建蹄,像睡著了一般碌更。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洞慎,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天痛单,我揣著相機與錄音睁宰,去河邊找鬼搂妻。 笑死,一個胖子當(dāng)著我的面吹牛京痢,可吹牛的內(nèi)容都是我干的焦人。 我是一名探鬼主播挥吵,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼花椭!你這毒婦竟也來了忽匈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤矿辽,失蹤者是張志新(化名)和其女友劉穎丹允,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袋倔,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡雕蔽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了宾娜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片批狐。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖前塔,靈堂內(nèi)的尸體忽然破棺而出嚣艇,到底是詐尸還是另有隱情,我是刑警寧澤华弓,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布髓废,位于F島的核電站,受9級特大地震影響该抒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜顶燕,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一凑保、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涌攻,春花似錦欧引、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽憋肖。三九已至,卻和暖如春婚苹,著一層夾襖步出監(jiān)牢的瞬間岸更,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工膊升, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怎炊,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓廓译,卻偏偏與公主長得像评肆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子非区,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容