MYSQL编码问题的汇总

来源:互联网 发布:aws sdk for php 编辑:程序博客网 时间:2024/04/29 03:03

MYSQL编码问题的汇总

上一篇 / 下一篇  2007-11-05 14:39:12/ 个人分类:他山之石

查看( 882 ) / 评论( 1 ) / 评分( 0 / 0 )

全文摘自[http://hi.baidu.com/kkwtre/blog/item/c5ef108254b732a30cf4d2ba.html]

1.   常规字符集和校对
MySQL5.1能够做这些事情:

·使用多种字符集来存储字符串

·使用多种校对规则来比较字符串

·在同一台服务器、同一个数据库或甚至在同一个表中使用不同字符集或校对规则来混合字符串

·允许定义任何级别的字符集和校对规则


2. MySQL中的字符集和校对
MySQL服务器能够支持多种字符集。可以使用SHOW CHARACTER SET语句列出可用的字符集:

mysql> SHOW CHARACTER SET


3. 确定默认字符集和校对
字符集和校对规则有4个级别的默认设置:服务器级、数据库级、表级和连接级。以下描述可能显得复杂,但是在实际应用中可以发现使用多种级别会使结果自然而明显。

MySQL按照如下方法确定服务器字符集和服务器校对规则:

·当服务器启动时根据有效的选项设置

·根据运行时的设定值

在服务器级别,确定方法很简单。当启动mysqld时,根据使用的初始选项设置来确定服务器字符集和校对规则。可以使用--default-character-set设置字符集,并且可以在字符集后面为校对规则添加--default-collation。如果没有指定一个字符集,那就与--default-character-set=latin1相同。

当前的服务器字符集和校对规则可以用作character_set_server和collation_server系统变量的值。在运行时能够改变这些变量的值。

 

3.2. 数据库字符集和校对
每一个数据库有一个数据库字符集和一个数据库校对规则,它不能够为空。CREATE DATABASE和ALTER DATABASE语句有一个可选的子句来指定数据库字符集和校对规则:
CREATE DATABASE db_name
     [[DEFAULT] CHARACTER SET charset_name]
     [[DEFAULT] COLLATE collation_name]

ALTER DATABASE db_name
     [[DEFAULT] CHARACTER SET charset_name]
     [[DEFAULT] COLLATE collation_name]
例如:

CREATE DATABASE db_name
     DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;

MySQL这样选择数据库字符集和数据库校对规则:

·如果指定了CHARACTER SET X和COLLATE Y,那么采用字符集X和校对规则Y。

·如果指定了CHARACTER SET X而没有指定COLLATE Y,那么采用CHARACTER SET X和CHARACTER SET X的默认校对规则。

·否则,采用服务器字符集和服务器校对规则。

如果在CREATE TABLE语句中没有指定表字符集和校对规则,则使用数据库字符集和校对规则作为默认值。


3.3. 表字符集和校对
每一个表有一个表字符集和一个校对规则,它不能为空。为指定表字符集和校对规则,CREATE TABLE 和ALTER TABLE语句有一个可选的子句:
CREATE TABLE tbl_name (column_list)
     [DEFAULT CHARACTER SET charset_name [COLLATE collation_name]]

ALTER TABLE tbl_name
     [DEFAULT CHARACTER SET charset_name] [COLLATE collation_name]
例如:

CREATE TABLE t1 ( ... )
DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;

MySQL按照下面的方式选择表字符集和 校对规则:

·如果指定了CHARACTER SET X和COLLATE Y,那么采用CHARACTER SET X和COLLATE Y。

·如果指定了CHARACTER SET X而没有指定COLLATE Y,那么采用CHARACTER SET X和CHARACTER SET X的默认校对规则。

·否则,使用数据库字符集和校对规则作为默认值。

如果在列定义中没有指定列字符集和校对规则,则默认使用表字符集和校对规则。表字符集和校对规则是MySQL的扩展;在标准SQL中没有。


3.4. 列字符集和校对
每一个“字符”列(即,CHAR、VARCHAR或TEXT类型的列)有一个列字符集和一个列 校对规则,它不能为空。列定义语法有一个可选子句来指定列字符集和校对规则:
col_name {CHAR | VARCHAR | TEXT} (col_length)
     [CHARACTER SET charset_name [COLLATE collation_name]]
例如:

CREATE TABLE Table1

(

     column1 VARCHAR(5) CHARACTER SET latin1 COLLATE latin1_german1_ci

);

MySQL按照下面的方式选择列字符集和校对规则:

·如果指定了CHARACTER SET X和COLLATE Y,那么采用CHARACTER SET X和COLLATE Y。

·如果指定了CHARACTER SET X而没有指定COLLATE Y,那么采用CHARACTER SET X和CHARACTER SET X的默认校对规则。

·否则,采用表字符集和服务器校对规则。


CHARACTER SET和COLLATE子句是标准的SQL。


举例子:

示例1:表和列定义

CREATE TABLE t1
(
     c1 CHAR(10) CHARACTER SET latin1 COLLATE latin1_german1_ci
) DEFAULT CHARACTER SET latin2 COLLATE latin2_bin;
在这里我们有一个列使用latin1字符集和latin1_german1_ci校对规则。是显式的定义,因此简单明了。需要注意的是,在一个latin2表中存储一个latin1列不会存在问题。

示例2:表和列定义

CREATE TABLE t1
(
     c1 CHAR(10) CHARACTER SET latin1
) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;
这次我们有一个列使用latin1字符集和一个默认校对规则。尽管它显得自然,默认校对规则却不是表级。相反,因为latin1的默认校对规则总是latin1_swedish_ci,列c1有一个校对规则latin1_swedish_ci(而不是latin1_danish_ci)。

示例3:表和列定义

CREATE TABLE t1
(
     c1 CHAR(10)
) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;
我们有一个列使用一个默认字符集和一个默认校对规则。在这种情况下,MySQL查找表级别来确定列字符集和 校对规则。因此,列c1的字符集是latin1,它的 校对规则是latin1_danish_ci。

示例4:数据库、表和列定义

CREATE DATABASE d1
     DEFAULT CHARACTER SET latin2 COLLATE latin2_czech_ci;
USE d1;
CREATE TABLE t1
(
     c1 CHAR(10)
);
我们创建了一个没有指定字符集和校对规则的列。我们也没有指定表级字符集和校对规则。在这种情况下,MySQL查找数据库级的相关设置。(数据库的设置变为表的设置,其后变为列的设置。)因此,列c1的字符集为是latin2,它的 校对规则是latin2_czech_ci。


3.6. 连接字符集和校对
一些字符集和校对规则系统变量与客户端和服务器的交互有关。
·服务器字符集和校对规则表示为character_set_server和collation_server变量的值。

·默认数据库的字符集和校对规则表示为character_set_database和collation_database变量的值。

考虑什么是一个“连接”:它是连接服务器时所作的事情。客户端发送SQL语句,例如查询,通过连接发送到服务
器。服务器通过连接发送响应给客户端,例如结果集。对于客户端连接,这样会导致一些关于连接的字符集和
校对规则的问题,这些问题均能够通过系统变量来解决:

·当查询离开客户端后,在查询中使用哪种字符集?

答:服务器使用character_set_client变量作为客户端发送的查询中使用的字符集。


·服务器接收到查询后应该转换为哪种字符集?

答:转换时,服务器使用character_set_connection和collation_connection系统变量。
它将客户端发送的查询从character_set_client系统变量转换到character_set_connection


·服务器发送结果集或返回错误信息到客户端之前应该转换为哪种字符集?

答:character_set_results变量指示服务器返回查询结果到客户端使用的字符集。包括结果数据,
例如列值和结果元数据(如列名)。


有两个语句影响连接字符集:
SET NAMES 'charset_name'
SET CHARACTER SET charset_name
SET NAMES显示客户端发送的SQL语句中使用什么字符集。

SET NAMES 'x'语句与这三个语句等价:
mysql> SET character_set_client = x;
mysql> SET character_set_results = x;
mysql> SET character_set_connection = x;


摘自:http://java.ccidnet.com/art/3737/20060605/571481_1.html

mysql 字符集


一. 显示字符集

mysqladmin -uroot -proot variables | grep character


| character_set_client | latin1 |

| character_set_connection | latin1 |

| character_set_database | latin1 |

| character_set_results | latin1 |

| character_set_server | latin1 |

| character_set_system | utf8 |

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


数据库缺省使用latin1 (ISO-8859)


二. 配置字符集


1. 建库时配置字符集


create database testxxx default charset=utf8


3. 建表时配置字符集


CREATE TABLE `t_agent` (

`ID` smallint(5) NOT NULL

) DEFAULT CHARSET=utf8 ;


4. 修改字符集


Windows平台

windows下的mysql配置文件是my.ini,一般在c:/windows/my.ini或者c:/winnt/my.ini可以直接在这个文件里面加上

default-character-set=gbk #或gb2312,big5,utf8

然后重新启动mysql

service mysql restart

/etc/init.d/mysql restart

或用其他方法重新启动,就生效了。


[编辑]Unix平台

linux下的mysql配置文件是my.cnf,一般是/etc/my.cnf,如果找不到可以用find命令找一下:

find / -iname my.cnf

在这个文件里面加上

default-character-set=gbk #或gb2312,big5,utf8

然后重新启动mysql


三. 配置排序字符集


myisamchk -r -q --set-character-set=charset


摘自:http://imysql.cn/?q=node/20
小谈MySQL字符集
首先,这片文章纯粹是我的个人经验之谈,适用于我常见的环境及项目中.
个人建议,数据库字符集尽量使用utf8(HTML页面对应的是utf-8),以使你的数据能很顺利的实现迁移,因为utf8字符集是目前最适合于实现多种不同字符集之间的转换的字符集,尽管你在命令行工具上可能无法正确查看数据库中的内容,我依然强烈建议使用utf8作为默认字符集.
接下来是完整的一个例子:
1.创建数据库表
mysql>CREATE DATABASE IF NOT EXISTS my_db default charset utf8 COLLATE utf8_general_ci;
#注意后面这句话 "COLLATE utf8_general_ci",大致意思是在排序时根据utf8校验集来排序
#那么在这个数据库下创建的所有数据表的默认字符集都会是utf8了

mysql>create table my_table (name varchar(20) not null default '')type=myisam default charset utf8;
#这句话就是创建一个表了,制定默认字符集为utf8

2.写数据
例子1是通过php直接插入数据:
a.php
<?php
mysql_connect('localhost','user','password');
mysql_select_db('my_db');

//请注意,这步很关键,如果没有这步,所有的数据读写都会不正确的
//它的作用是设置本次数据库联接过程中,数据传输的默认字符集
//其他编程语言/接口也类似,例如 .net/c#/odbc
//jdbc则设置连接字符串为类似"jdbc:mysql://localhost/db?user=user&password=123456&useUnicode=true&characterEncoding=UTF-8"

mysql_query("set names utf8;");
//必须将gb2312(本地编码)转换成utf-8,也可以使用iconv()函数
mysql_query(mb_convet_encoding("insert into my_table values('测试');", "utf-8", "gb2312"));
?>

例子是通过页面提交插入数据2:
b.php
<?php
//输出本页编码为utf-8
header("content-type:text/html; charset=utf-8");

mysql_connect('localhost','user','password');
mysql_select_db('my_db');

mysql_query("set names utf8;");
if(isset($_REQUEST['name'))
{
//由于上面已经指定本页字符集为utf-8了,因此无需转换编码
mysql_query(sprintf("insert into my_table values('%s');", $_REQUEST['name']));
}

$q = mysql_query("select * from my_table");
while($r = mysql_fetch_row($q))
{
print_r($r);
}
?>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<form action="" method="post">
<input type="text" name="name" value="">
<input type="submit" value='submit'>
</form>

自此,使用utf8字符集的完整的例子结束了.
如果你想使用gb2312编码,那么建议你使用latin1作为数据表的默认字符集,这样就能直接用中文在命令行工具中插入数据,并且可以直接显示出来.而不要使用gb2312或者gbk等字符集,如果担心查询排序等问题,可以使用binary属性约束,例如:
create table my_table ( name varchar(20) binary not null default '')type=myisam default charset latin1;

附1:旧数据升级办法
以原来的字符集为latin1为例,升级成为utf8的字符集。原来的表: old_table (default charset=latin1),新表:new_table(default charset=utf8)。
第一步:导出旧数据
mysqldump --default-character-set=latin1 -hlocalhost -uroot -B my_db --tables old_table > old.sql
第二步:转换编码(类似unix/linux环境下)
iconv -t utf-8 -f gb2312 -c old.sql > new.sql
或者可以去掉 -f 参数,让iconv自动判断原来的字符集
iconv -t utf-8 -c old.sql > new.sql
在这里,假定原来的数据默认是gb2312编码。
第三步:导入
修改old.sql,在插入/更新语句开始之前,增加一条sql语句:

"SET NAMES utf8;",保存。
mysql -hlocalhost -uroot my_db < new.sql
大功告成!!

附2:支持查看utf8字符集的MySQL客户端有
1.) MySQL-Front,据说这个项目已经被MySQL AB勒令停止了,不知为何,如果国内还有不少破解版可以下载(不代表我推荐使用破解版 :-P)。
2.) Navicat,另一款非常不错的MySQL客户端,汉化版刚出来,还邀请我试用过,总的来说还是不错的,不过也需要付费。
3.) PhpMyAdmin,开源的php项目,非常好。
4.) Linux下的终端工具(Linux terminal),把终端的字符集设置为utf8,连接到MySQL之后,执行 SET NAMES UTF8; 也能读写utf8数据了。


6步解决mysql字符集问题(php utf-8乱码问题)   大 | 中 | 小   Tags: apache , php , 服务器配置
6步解决mysql字符集问题(php utf-8乱码问题)

1.my.ini:
[mysql]
default-character-set=utf8
[mysqld]
default-character-set=utf8
default-storage-engine=MyISAM
在[mysqld]下加入:
default-collation=utf8_bin
init_connect='SET NAMES utf8'

2.在需要做数据库操作的php程序前面加上
mb_internal_encoding('utf-8');

3.create table最后边加上ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin

4.phpMyAdmin/config.inc.php
$cfg['DefaultCharset'] = 'utf-8';
$cfg['RecodingEngine'] = 'iconv';

5.phpMyAdmin/libraries/string.lib.php
将第41行的
mb_internal_encoding($GLOBALS['charset']);
改为:mb_internal_encoding('utf-8');

6.phpAdmin导出数据时
把"二进制区域使用十六进制显示"的勾去掉


简单总结下:

执行 SHOW VARIABLES LIKE 'Charater_set%'可查看MySQL关于Character set的各个设置:

影响服务器和客户端数据传输的有

character_set_client 决定服务器接受客户端发送的数据时采用的字符集
character_set_connection 服务器将客户端传来的数据由character_set_client转换到character_set_connection
character_set_results 决定服务器向客户端发送数据采用的字符集

网上大部分文章中提到两种方法指定传输时使用的字符集

SET NAMES 'charset_name'
SET CHARACTER SET charset_name

SET NAMES 'x' 等效于
SET character_set_client = x;
SET character_set_results = x;
SET character_set_connection = x;


SET CHARACTER SET 'x'   等效于
SET character_set_client = x;
SET character_set_results = x;
SET collation_connection = @@collation_database; --数据库的collation

所以,如果client和server端的默认character set不一致,则需要在读取和写入数据之前先query一句SETCHARACTER SET 'x'或SET NAMES 'x','x'为client使用的characterset。也可以使用mysqli_set_charset (PHP 5 >= 5.1.0RC1)


摘自http://kubbs.net/showart.asp?art_id=16989&cat_id=34

mysql4.1及其之后的版本,对字符集的支持分为四个层次: 服务器(server),数据库(database),数据表(table)和连接(connection):
character_set_server:这是设置服务器使用的字符集
character_set_client :这是设置客户端发送查询使用的字符集
character_set_connection :这是设置服务器需要将收到的查询串转换成的字符集
character_set_results :这是设置服务器要将结果数据转换到的字符集,转换后才发送给客户端

整个过程:
- client(如php程序)发送一个查询;
- 服务器收到查询,将查询串从character_set_client 转换到character_set_connection,然后执行转换后的查询;
- 服务器将结果数据转换到character_set_results字符集后发送回客户端。

你可以用下边两条命令查看一下系统的字符集和排序方式设定:
mysql> SHOW VARIABLES LIKE ‘character_set_%’;
mysql> SHOW VARIABLES LIKE ‘collation_%’;

mysql 默认用的字符集是latin1,连接校对用的latin1-_swedish_ci。看到这儿你应试有点明白了,
我们通过php发送的查询一般是utf8或者GBK,GB2312,而它默认的是latin1,所以用phpmyadmin查看或
者直接进数据库里查看数据,都是一些乱码。(存取出来放在网页上大多是正常的。)phpmyadmin
在对mysql4.0以下会使用内置的库来实现字符集的转换,从而支持多语言版本,而对于4.1以上则完
全交给Mysql。所以以上几个层次的转换如果有字符集不匹配的情况,出现乱码就很容易理解了。
说了半天,其实你只要把上述变量设置一致了,不管是直接在数据库里查看,还是在phpmyadmin里
查看都不会出现中文乱码了。

假如你的系统和php网页是utf8编码,你可以将mysql的编码由默认的latin1改为utf8.
编辑mysql的配置文件,/etc/my.cnf,在[mysqld]中设置default-character-set=utf8即可。


摘自http://www.syict.com/html/2/2-10322.html的一部分

a.   Mysql一定有一个字符集,可以通过启动时加参数指定 ,也可以编译时指定,也可以在配置文件里指定。
Mysql服务器字符集,只是做为数据库级的默认值。创建数据库时,你可以指定字符集,如果没指定,
就使用服务器的字符集。同理,创建表时,你可以指定表级的字符集,如果没指定,使用数据库的字符集
做为表的字符集。创建列时,你可以指定某列的字符集,如果没指定,就使用表的字符集。 通常情况下,
您只需设置服务器级的字符集,其它的数据库级,表级,以及列级的字符集,都继承自服务器级字符集。
由于UTF8是最广的字符集,所以,一般情况下,我们设置Mysql服务器级的字符集为UTF8!

b.   HTML是文本文件。存储HTML文件的时候,需要使用一个编码,并且,在HTML文件里,也使用HTML语法,
指定了该文件所使用的编码。如果HTML文件没有指定编码,则浏览器自动识别文件的编码。
如果HTML指定了编码,则浏览器使用HTML指定的编码。 通常情况下,HTML文件指定的charset和HTML文件
自身的编码是一致的,但也有不一致的情况,如果不一致,就会导致网页乱码(此处乱码,只和文本文件有关,
和数据库无关。)使用专门的网页编辑工具(比如Dreamwave),会自动根据网页中的charset值来编码文件。

c.php+mysql的字符集问题

要保证不乱码(包括浏览器显示不是乱码),就必须将三个编码统一:
一是网页自身的编码,
二是HTML里指定的编码(即建议浏览器显示所用的编码),
三是PHP告诉Mysql的编码
(包括character_set_client和character_set_results)。

第一和第二个编码,如果使用DW之类的编辑器写的网页,通常是一致的,但用记事本写的网页,有可能不一致。 沈阳化工学院.学生站,E ] /&C O1a T"]
第三个编码,需要手工通知Mysql。这步可以通过在PHP里使用mysql_query(“set names characterX”)来实现。

总结:
1.数据库尽量使用utf8存储(修改/etc/my.cnf,在[mysqld]段加上default-character-set=utf8)
(已有的数据库,先转成UTF8格式)

2.PHP程序在查询数据库之前,执行mysql_query(“set names xxxx”);
其中xxxx是你网页的编码(charset=xxxx),如果网页中charset=utf8,则xxxx=utf8,
如果网页中charset=gb2312,则xxxx=gb2312,几乎所有WEB程序,都有一段连接数据库的公共代码
放在一个文件里,在这文件里,加入mysql_query(“set names”)就可以了。

3.PHPMyAdmin不需要做改动。

4.需要注意的是,为保证网页实际编码(Windows保存对话框里的编码)和他声明的编码(charset=?)是一致的,请用DW之类的工具做网页。

原创粉丝点击