对于语言编码,MySQL都为我们做了什么

xuzuning 2010-08-06 04:32:12
经常有朋友问到 mysql 的乱码问题。得到的答案多半是说:要保证编码一致,甚至php程序文件也要做到编码一致。

其实不然!

背景:
我还是在 mysql4 时代使用过 mysql,他没有编码问题,但也没有存储过程。所以就改用 sql server 了。最近因项目需求,又把 mysql 捡起来了。也测试了一下 mysql 的语言编码问题
我安装的是 mysql 5.1.47 版本,安装时选则了 utf8 作为默认语言
但我仍然喜欢使用 gbk 编码,因为编辑 utf-8 编码的文件需要用编程工具,而我只喜欢用 记事本

于是我在上述环境中以 DEFAULT CHARSET=gbk 建库建表
并在 mysql_query('set names gbk'); 之后进行数据库操作。一直如此,并无任何问题。

后来有一个必须为 utf-8 编码的页面,他还要使用那个 gbk 编码的库中的数据。怎么办呢?直接的想法就是取出数据后再用 iconv 函数转码。很是费劲吧?

其实 mysql 已经做的很好了,只需要设置一下语言
mysql_query('set names utf8');
于是查询结果都是 utf-8 编码的了
不错!
于是我向 gbk 编码的表中插入 utf-8 编码的数据,然后用 gbk 编码读回(set names gbk)
真不错!
刚才插入的数据已然以 gbk 编码展示,一点乱码也没有


请有兴趣的朋友发表高论!
谢绝顶贴!

...全文
497 51 打赏 收藏 转发到动态 举报
写回复
用AI写文章
51 条回复
切换为时间正序
请发表友善的回复…
发表回复
ruanchao 2010-08-10
  • 打赏
  • 举报
回复
看似基础性的问题,如果不知其所以然,也会被搞迷糊的。

赞一个
yhr7289864 2010-08-10
  • 打赏
  • 举报
回复
<?php
header("Content-type:text/html;Charset=UTF-8;");
$link=mysql_connect("localhost","root","123456") or die("无法连接服务!");
mysql_select_db("codegbk",$link) or die("数据库无法选择");
mysql_query("set names utf8");
$rs = mysql_query("select *from user",$link);

$sql = "insert into user values(default,'测试乱码')";
mysql_query($sql);
while($row = mysql_fetch_array($rs)){
echo $row["username"]."<br/>";
}
?>

经过几次乱码的测试,只要在插入数据时候 set names 这个编码与页面的编码统一,而与数据库的编码无关系。在读数据的时候set names 这个编码与页面编码统一,也就相当与 set names 是告诉mysql 我要读取和存储什么样的编码数据。现在页面一直未出现问题.
wll474127597 2010-08-09
  • 打赏
  • 举报
回复
我还以为是什么高深的技术诶!
wll474127597 2010-08-09
  • 打赏
  • 举报
回复
汗,做PHP的谁不知道这个,居然跑论坛来发这个!
vov123 2010-08-09
  • 打赏
  • 举报
回复
我从数据库输出的时候是
$con=@mysql_connect("localhost","root","123") or die("数据库无法连接");
$db=@mysql_select_db("my") or die("库无法连接");
header("Content-Type:text/html;charset=utf-8");
执行updata 语句的时候是
$con=@mysql_connect("localhost","root","123") or die("数据库无法连接");
$db=@mysql_select_db("my") or die("库无法连接");
mysql_query("set names GB2312");
这样不会有乱码 可是要是同一个网页同时执行这两个操作就乱了。。。。怎么办?都说要统一编码 可是怎么把所有的编码都设置统一啊
c461439564 2010-08-09
  • 打赏
  • 举报
回复
语言混编就没弄过了,统一编码是正道,其它的申明执行命令过于麻烦、易出问题
LKK 2010-08-09
  • 打赏
  • 举报
回复
学习来了。。
helloyou0 2010-08-08
  • 打赏
  • 举报
回复
唠叨, 27楼, 38楼说的都是对的。

mysql的转换过程就是
存入时:character_set_client =〉
character_set_connection =〉
character_set_database(table/column )

取出时:character_set_database(table/column ) =〉
character_set_connection =〉
character_set_results

这个转换中,字符集必须相容(能一一对应当然最好),如果有latin1这样字符数很少的字符集,转换后必然会有字符丢失。

我以前回复的帖子里有解释得更详细的,可以搜索到。




Dleno 2010-08-08
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 quzhongxiong 的回复:]

前段时间我也发现一个非常奇怪的问题,就是MYSQL用的都是UTF8,页面用的也是UTF8,但为了避免乱码的问题,我还是加上了set names 'utf-8',这下问题就来了,乱码,百思不得其解,编码都是一样的,为什么会乱码呢,搞了好久,于是死马当活马医,把set names 'utf-8'改成set names 'utf8',怪了,又好了,所以顺便也想问一下各位,难道"utf8"与"utf-8……
[/Quote]

mysql里只有utf8,没有utf-8的编码名字
foolbirdflyfirst 2010-08-08
  • 打赏
  • 举报
回复
set names utf8有3个过程
---------------------------------------------
set character_set_client utf8; #通知mysql,客户端发送的是utf-8编码数据
set character_set_connection utf8 ;#客户端编码与存储引擎连接校对
set character_set_results utf8 ; #从存储引擎得到的数据转成utf8返回给客户端

mysql帮我们完成了转换过程,不管是客户端gbk访问utf-8数据库,还是utf-8客户端访问gbk数据库,都没问题。
统一编码是为了系统的多语言性,移植性。
gbk的页面读其它语言的数据就肯定错了。
gbk要成为世界标准,最起码先得支持世界各国文字,编码区得扩充到和unicode一样。
pak001 2010-08-08
  • 打赏
  • 举报
回复
本人用phpmyadmin经常乱码,不知道是不是mysql的问题
steptodream 2010-08-08
  • 打赏
  • 举报
回复
最烦乱码问题了
全世界统一使用英文 统一编码就好了
xuzuning 2010-08-08
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 coolesting 的回复:]
假如,有一天,你的数据库要和别的应用程序共享数据,
那程序默认了utf-8,当调用你的数据时发现是gbk怎么办?

那么,默认情况下该程序就可能不正常显示你的数据了,
好比,你做好的作品给用户,而这些用户通常是白痴(对于计算机来说),
他们不懂设置这个那个,甚至也是根本看不明白后台管理的术语。



下面举两个例子:

再假设,我写程序时,都标了英文注解(utf-8),
……
[/Quote]
[Quote=引用 36 楼 coolesting 的回复:]
你可以用任何编码,只要mysql支持的,
关键你用这种编码存储时,当调用那一方也要支持,

但调用的程序目前可能是自己,但当别人来调用时,
别人也是否支持这种编码格式的数据呢?


我想这个原理大概和Web Service一样,如果不用统一的协议,很难说是什么结论。
[/Quote]

也正是这个原因,所以你用你的 utf-8 程序访问我的 gbk 数据库时只要声明一下 set names utf8 ,于是我的数据库就以 utf-8 编码向你提供数据;而我的 gbk 程序要从你的 utf8 数据库得到数据,也只需通知你的数据库 set names gbk 我需要 gbk 编码的数据

如果仅仅是为了所谓的“统一”,那么为什么不统一到 gbk 下呢?你如何知道中国标准不会成为世界标准呢
quzhongxiong 2010-08-07
  • 打赏
  • 举报
回复
前段时间我也发现一个非常奇怪的问题,就是MYSQL用的都是UTF8,页面用的也是UTF8,但为了避免乱码的问题,我还是加上了set names 'utf-8',这下问题就来了,乱码,百思不得其解,编码都是一样的,为什么会乱码呢,搞了好久,于是死马当活马医,把set names 'utf-8'改成set names 'utf8',怪了,又好了,所以顺便也想问一下各位,难道"utf8"与"utf-8"这两种不同的写法造成的处理方式还会不同??
xuzuning 2010-08-07
  • 打赏
  • 举报
回复
这是测试例
mysql_connect();
mysql_select_db('test');
mysql_query('DROP TABLE IF EXISTS `mb`);
$sql = <<< SQL
CREATE TABLE `mb` (
`ch` varchar(10) NOT NULL,
`val` varchar(50) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk;
SQL;
mysql_query($sql);

function save($charset, $text) {
mysql_query("set names $charset");
mysql_query("insert into mb values ('$charset', '$text')");
}

function load($charset) {
mysql_query("set names $charset") or die(mysql_error());
$rs = mysql_query('select * from mb');
while($row = mysql_fetch_assoc($rs)) {
list($hex) = unpack('H*0', $row[val]);
echo "$charset $row[ch] : $row[val] $hex<br>";
}
}

$s = "漢字";

save('gbk', $s);
save('utf8', iconv('gbk', 'utf-8', $s));
save('big5', iconv('gbk', 'big5', $s));

load('gbk');
load('utf8');
load('big5');
xuzuning 2010-08-07
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 piger920 的回复:]
涉及3种编码的话 有问题 (测试是 表为latin1 插入gbk 读出utf8)
[/Quote]
latin1 是单字节编码,估计有点问题。

不过 php168 在安装时建议编码是 latin1
对于这个有何高论?!

漫漫2009 2010-08-07
  • 打赏
  • 举报
回复
同意楼主的观点,mysql表中的内容以gbk还是utf8格式存储的并不重要,重要的是当我们从mysql中存取数据时要告诉mysql我们使用的是什么编码。也就是设置好set names 编码

另外附个网上找来的以十六进制查看字符串的函数:

function binhex($str) {
$hex = "";
$i = 0;
do {
$hex .= sprintf("%02x", ord($str{$i}));
$i++;
}
while ($i < strlen($str));
return $hex;
}
骄傲青蛙 2010-08-07
  • 打赏
  • 举报
回复
你可以用任何编码,只要mysql支持的,
关键你用这种编码存储时,当调用那一方也要支持,

但调用的程序目前可能是自己,但当别人来调用时,
别人也是否支持这种编码格式的数据呢?


我想这个原理大概和Web Service一样,如果不用统一的协议,很难说是什么结论。
骄傲青蛙 2010-08-07
  • 打赏
  • 举报
回复
假如,有一天,你的数据库要和别的应用程序共享数据,
那程序默认了utf-8,当调用你的数据时发现是gbk怎么办?

那么,默认情况下该程序就可能不正常显示你的数据了,
好比,你做好的作品给用户,而这些用户通常是白痴(对于计算机来说),
他们不懂设置这个那个,甚至也是根本看不明白后台管理的术语。



下面举两个例子:

再假设,我写程序时,都标了英文注解(utf-8),
当我有天心血来潮时突然要发布到sourceforge或code.google,
如果当时我用中文注解(gbk),那岂不是又要重新一次?

其实,平时我们尽都可以说家乡话(gbk),但为什么还要说普通话(utf-8)来交流,
但习惯了家乡话的人上网时会说一些别人看不明的术语。



人类有人类的语言,机械有机械的语言,我们选择统一的语言是为了更好的交流,
但这个统一需要平时的习惯来作支撑。


------ 卑人浅见,多谢指教
无天 2010-08-06
  • 打赏
  • 举报
回复
mark,楼主这方法倒不错。
加载更多回复(28)
MySQL 教程MySQL 是流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。在本教程中,会让大家快速掌握 MySQL 的基本知识,并轻松使用 MySQL 数据库。什么是数据库?数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。每个数据库都有一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据。我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理大数据量。所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。RDBMS 即关系数据库管理系统(Relational Database Management System)的特点:1.数据以表格的形式出现2.每行为各种记录名称3.每列为记录名称所对应的数据域4.许多的行和列组成一张表单5.若干的表单组成databaseRDBMS 术语 在我们开始学习MySQL 数据库前,让我们先了解下RDBMS的一些术语:数据库: 数据库是一些关联表的集合。数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。列: 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。外键:外键用于关联两个表。复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。MySQL 为关系型数据库(Relational Database Management System), 这种所谓的关系型可以理解为表格的概念, 一个关系型数据库由一个或数个表格组成, 如图所示的一个表格: 表头(header): 每一列的名称;列(col): 具有相同数据类型的数据的集合;行(row): 每一行用来描述某条记录的具体信息;值(value): 行的具体信息, 每个值必须与该列的数据类型相同;键(key): 键的值在当前列中具有唯一性。MySQL数据库MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL 是开源的,目前隶属于 Oracle 旗下产品。MySQL 支持大型的数据库。可以处理拥有上千万条记录的大型数据库。MySQL 使用标准的 SQL 数据语言形式。MySQL 可以运行于多个系统上,并且支持多种语言。这些编程语言包括 C、C++、Python、Java、Perl、PHP、Eiffel、Ruby 和 Tcl 等。MySQL 对PHP有很好的支持,PHP 是目前流行的 Web 开发语言MySQL 支持大型数据库,支持 5000 万条记录的数据仓库,32 位系统表文件最大可支持 4GB,64 位系统支持最大的表文件为8TB。MySQL 是可以定制的,采用了 GPL 协议,你可以修改源码来开发自己的 MySQL 系统。Redis 教程REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧