UTF-8和GBK编码之间的区别(页面编码、数据库编码区别)以及在实际项目中的应用

第一节:UTF-8和GBK编码概述

UTF-8 (8-bit Unicode Transformation Format) 是一种针对Unicode的可变长度字符编码,又称万国码,它包含全世界所有国家需要用到的字符,是国际编码,通用性强,是用以解决国际上字符的一种多字节编码。由Ken Thompson于1992年创建。UTF-8用1到4个字节编码UNICODE字符,它对英文使用8位/8Bit(即1个字节/1Byte),中文使用24位/24Bit(3个字节/3Byte)来编码。用在网页上可以同一页面显示中文简体繁体及其它语言(如日文,韩文)。

GBK (Chinese Internal Code Specification) 是汉字编码标准之一,全称《汉字内码扩展规范》,中华人民共和国全国信息技术标准化技术委员会1995年12月1日制订,国家技术监督局标准化司、电子工业部科技与质量监督司1995年12月15日联合以技监标函1995 229号文件的形式,将它确定为技术规范指导性文件。
GBK是国家标准GB2312基础上扩容后兼容GB2312的标准(GB2312共收录了7445个字符,包括6763个汉字和682个其它符号;GBK共收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字)。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示(注意,GB系列编码是利用了字节中的最高位和ASCII编码区分的,可以和ASCII码混用。所以全角模式下英文是2字节,半角模式英文还是1字节)。为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。

简单概况就是:
UTF-8英文1字节中文3字节,在编码效率和编码安全性之间做了平衡,适合网络传输,是理想的中文编码方式.
GBK英文1字节(半角1字节,全角2字节),中文2字节,GBK的范围比GB2312广,GBK兼容GB2312。

参考文章:
http://blog.csdn.net/mydriverc2/article/details/50525203
http://blog.csdn.net/liudajiang/article/details/41133077
http://www.cnblogs.com/xiaomia/archive/2010/11/28/1890072.html

第二节:UTF-8和GBK在Web传输中的区别

PHP示例代码:

$str=‘中文‘; // 2个中文
echo strlen($str),‘,‘; // UTF-8长度是:6 (UTF-8编码: 1个中文3byte,2个中文加起来是6byte)
echo strlen(iconv(‘utf-8‘, ‘GBK‘, $str)),‘,‘; // GBK长度是:4 (GBK编码:1个中文2byte,2个中文加起来是4byte)

$str=‘a0‘; // 1个英文1个数字
echo strlen($str),‘,‘; // UTF-8长度是:2 (UTF-8编码: 1个英文或数字是1byte,1个英文和1个数字加起来是2byte)
echo strlen(iconv(‘utf-8‘, ‘GBK‘, $str)),‘,‘; // GBK长度是:2 (GBK编码:1个英文或数字是1byte, 1个英文和1个数字加起来是2byte)

$str=‘E汉‘; // 1个英文1个中文
echo strlen($str),‘,‘; // UTF-8长度是:4 (UTF-8编码: 1个中文3byte,1个英文1byte,加起来是4byte)
echo strlen(iconv(‘utf-8‘, ‘GBK‘, $str)); // GBK长度是:3 (GBK编码:1个中文2byte,1个英文或数字是1byte, 加起来是3byte)

代码截图:

输出结果:

第三节:UTF-8和GBK在数据库存储中的区别

====================MySQL测试====================

MySQL示例代码(UTF8编码):
-- 创建指定UTF8编码的表
create table chartestutf8 (fstr varchar(2), fchr char(2)) DEFAULT CHARSET=UTF8;
-- 写入测试数据
insert into chartestutf8 (fstr, fchr) values (‘中文‘,‘中文‘);
insert into chartestutf8 (fstr, fchr) values (‘E文‘,‘E文‘);
insert into chartestutf8 (fstr, fchr) values (‘a0‘,‘a0‘);
-- 查询数据表内容
select fstr as ‘UTF8变长内容‘, LENGTH(fstr) as ‘UTF8变长内容长度‘, fchr as ‘UTF8定长内容‘, LENGTH(fchr) as ‘UTF8定长内容长度‘ from chartestutf8;

代码截图:

内容说明:
UTF-8用1到4个字节编码UNICODE字符,英文一个字节/1byte (8位/8bit),中文三个字节/3byte (24位/24bit)
‘中文‘ 2个汉字的长度是 3byte * 2 = 6byte
‘E文‘ 1个英文+1个汉字的长度是 1byte + 3byte = 4byte
‘a0‘ 1个英文+1个数字的长度是 1byte + 1byte = 2byte

MySQL示例代码(GBK编码):

-- 创建指定GBK编码的表
create table chartestgbk (fstr varchar(2), fchr char(2)) DEFAULT CHARSET=GBK;
-- 写入测试数据
insert into chartestgbk (fstr, fchr) values (‘中文‘,‘中文‘);
insert into chartestgbk (fstr, fchr) values (‘E文‘,‘E文‘);
insert into chartestgbk (fstr, fchr) values (‘a0‘,‘a0‘);
-- 查询数据表内容
select fstr as ‘GBK变长内容‘, LENGTH(fstr) as ‘GBK变长内容长度‘, fchr as ‘GBK定长内容‘, LENGTH(fchr) as ‘GBK定长内容长度‘ from chartestgbk;

代码截图:

内容说明:
GBK的文字编码用双字节来表示,即不论中、英文字符均使用双字节来表示
‘中文‘ 2个汉字的长度是 2byte * 2 = 4byte
‘E文‘ 1个英文+1个汉字的长度是 1byte + 2byte = 3byte
‘a0‘ 1个英文+1个数字的长度是 1byte + 1byte = 2byte

注意:varchar(N), 这里的N是指字符数,并不是字节数.占用的字节数与编码有关。

参考文章:
http://www.oschina.net/question/199396_37127

====================SQL Server测试====================

SQL Server示例代码(Varchar):
-- 创建表
create table chartest (fstr varchar(4), fchr char(4));
-- 写入测试数据
insert into chartest (fstr, fchr) values (‘中文‘,‘中文‘);
insert into chartest (fstr, fchr) values (‘E文‘,‘E文‘);
insert into chartest (fstr, fchr) values (‘a0‘,‘a0‘);

-- 查询数据表内容
-- DATALENGTH()函数返回的是字节数,一个汉字两个字节
select fstr as ‘变长内容‘, DATALENGTH(fstr) as ‘内容长度‘, fchr as ‘定长内容‘, DATALENGTH(fchr) as ‘内容长度‘ from chartest;
-- LEN()函数返回字符数,一个汉字代表一个字符
select fstr as ‘变长内容‘, LEN(fstr) as ‘字符个数‘, fchr as ‘定长内容‘, LEN(fchr) as ‘字符个数‘ from chartest;

代码截图:

SQL Server示例代码(NVarchar):

-- 创建表
create table chartestn (fstr nvarchar(2), fchr nchar(2));
-- 写入测试数据
insert into chartestn (fstr, fchr) values (‘中文‘,‘中文‘);
insert into chartestn (fstr, fchr) values (‘E文‘,‘E文‘);
insert into chartestn (fstr, fchr) values (‘a0‘,‘a0‘);
-- 查询数据表内容
-- DATALENGTH()函数返回的是字节数,一个汉字两个字节
select fstr as ‘变长内容‘, DATALENGTH(fstr) as ‘内容长度‘, fchr as ‘定长内容‘, DATALENGTH(fchr) as ‘内容长度‘ from chartestn;
-- LEN()函数返回字符数,一个汉字代表一个字符
select fstr as ‘变长内容‘, LEN(fstr) as ‘字符个数‘, fchr as ‘定长内容‘, LEN(fchr) as ‘字符个数‘ from chartestn;

代码截图:

内容说明:
‘中文‘ 2个汉字的长度是 2byte * 2 = 4byte,所以会提示将截断字符串或二进制数据的错误。
‘E文‘ 1个英文+1个汉字的长度是 1byte + 2byte = 3byte
‘a0‘ 1个英文+1个数字的长度是 1byte + 1byte = 2byte
SQL Server定长数据类型(char(n)),不足的补英文半角空格,所以查询出来的长度都是固定的。

项目应用:
varchar按实际字节长度存储,1个汉字1字节,1个英文1字节,长度1-8000。
nvarchar按字符数量存储,不论汉字或英文,都是2字节,长度1-4000。

补充知识:

sql server中的varchar和Nvarchar的区别:
1. Varchar是一个英文和一个汉字都站两个字节,长度介于1和8000之间,存储大小为输入数据的字节的实际长度
2. Nvarchar是一个英文占一个字节,汉字占两个字节,长度介于1与4000之间,存储大小是所输入字符个数的两倍(n前缀的,n表示Unicode字符,即所有字符都占两个字节)
3. 从存储方式上,nvarchar是按字符存储的,而 varchar是按字节存储的
4. 从存储量上考虑, varchar比较节省空间,因为存储大小为字节的实际长度,而 nvarchar是双字节存储
5. 如果你做的项目可能涉及不同国家语言之间的转换,建议用nvarchar,因为nvarchar是使用Unicode编码,会减少乱码的出现几率
6. Char/NChar固定长度数据类型,不足的补英文半角空格。

LEN()函数:返回给定字符串表达式的字符(而不是字节)个数,其中不包含尾随空格。(Len只返回字符数,一个汉字代表一个字符)
DATALENGTH()函数:返回任何表达式所占用的字节数。(Datalength返回的是字节数,一个汉字两个字节)
Len()不包含空格在内长度,而DATALENGTH()包含空格。

参考文章:
http://www.cnblogs.com/14lcj/archive/2012/07/08/2581234.html
http://blog.163.com/rihui_7/blog/static/212285143201211123342333/?NdsKey=246770


版权声明:本文采用署名-非商业性使用-相同方式共享(CC BY-NC-SA 3.0 CN)国际许可协议进行许可,转载请注明作者及出处。
本文标题:UTF-8和GBK编码之间的区别(页面编码、数据库编码区别)以及在实际项目中的应用
本文链接:http://www.cnblogs.com/sochishun/p/7026762.html
本文作者:SoChishun (邮箱:14507247#qq.com | 博客:http://www.cnblogs.com/sochishun/)
发表日期:2017年6月13日

时间: 2024-11-03 01:28:38

UTF-8和GBK编码之间的区别(页面编码、数据库编码区别)以及在实际项目中的应用的相关文章

Hbase总结(一)-hbase命令,hbase安装,与Hive的区别,与传统数据库的区别,Hbase数据模型

Hbase总结(一)-hbase命令 下面我们看看HBase Shell的一些基本操作命令,我列出了几个常用的HBase Shell命令,如下: 名称 命令表达式 创建表 create '表名称', '列名称1','列名称2','列名称N' 添加记录 put '表名称', '行名称', '列名称:', '值' 查看记录 get '表名称', '行名称' 查看表中的记录总数 count  '表名称' 删除记录 delete  '表名' ,'行名称' , '列名称' 删除一张表 先要屏蔽该表,才能对

页面数据写入数据库编码问题

最近写了一个小的爬虫代码.想要把抓取到的数据放入数据库中.发现报错 首先 百度,发现是由于编码问题造成的 先看数据库编码  show variables like 'character_set_database'; show create table <表名>; 发现果然编码不对,遂将编码修改为UTF-8 继续执行脚本,发现依然报错.心想是不是页面数据格式不是UTF-8 中间还需要做什么转换?  发现页面数据格式也是UTF-8.... 遂继续百度..终于 功夫不负有心人,发现了一个回答. 带着

UTF-8 GBK GB2312 之间的区别和关系

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

小数据池 (常量池 -&gt; 字符串缓存) is和==的区别 重新看编码 以及编码之间相互转化

?. 小数据池 在说小数据池之前. 我们先看一个概念念. 什么是代码块: 根据提示我们从官?方?文档找到了这样的说法: A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class defin

ASCII、GBK、unicode、utf-8、iso-8859-1等编码的发展史和相互关系

1.ASCII 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们认为8个开关状态作为原子单位很好,于是他们把这称为"字节". 再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出更多的状态,状态开始变来变去.他们看到这样是好的,于是它们就这机器称为"计算机". 开始计算机只在美国用.八位的字节一共可以组合出256(2的8次方)种不同的状态. 他们把其中的编号从0开始的32种状态分别规定了特殊的

浏览器正确理解和使用GBK及UTF-8(UTF-8 + BOM)网页编码

网页编码英文译为web page encoding,是在网页中指定其特定的字符编码格式的库. GBK是国家标准GB2312基础上扩容后兼容GB2312的标准.GBK的文字编码是用双字节来表示的,即不论中.英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1.GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大. UTF-8:Unicode TransformationFormat-8bit,允许含BOM,但通常不含BOM.是用以解决国际上字符的一种

记一个奇怪的编码转换问题,及探讨“错误: 编码GBK的不可映射字符” 的原因

什么情况? 下面的一段简单代码,发现了奇怪的编码问题: String docPath = "姝f枃";// docPath = "正文"; // 注释1System.out.println("default = " + docPath); String docPath1 = new String(docPath.getBytes(), "GBK");System.out.println("GBK = " +

Pdf与Base64编码之间的转换

在我们的工作有时候我们需要将图片或者pdf文件转换为Base64编码,然后从服务器端下载传输到本地,在这里我列举下两者之间的转换方法: Base64编码转换为pdf: /** * Description: 将base64编码内容转换为Pdf * @param base64编码内容,文件的存储路径(含文件名) * @Author fuyuwei * Create Date: 2015年7月30日 上午9:40:23 */ public static void base64StringToPdf(S

JavaSE(六)包装类、基本类型和字符串之间的转换、==和equals的区别

一.包装类 Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足, 在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class),有些地方也翻译为外覆类或数据类型类. 1.1.包装类均位于Java.lang包,包装类和基本数据类型的对应关系如下表所示: Primitive-Type   Wrapper-Class        byte