【问题来源】将设计的数据库表展示的时候,yu哥问我,你的那个top_info字段定义的类型是varchar(100),为什么是100呢,这100的长度能存多少个中文?

当时的想法就是,这个100能存多少个中文和数据库的编码方式有关,具体怎么个有关发还真是没有细细探究。为了搞清这一系列的问题,我百度了一下,但是网上的答案千奇百怪,很不给力,只能自己摸索了。

首先需要明确的是:utf8编码方式下,一个中文占3个字节;而gbk编码下,一个中文占2个字节。这个我们可以使用varchar类型存储一个字段vname,然后分别向其中添加一个汉字和英文,然后select length(vname) from tablename;然后我们添加进去的数据占多少个字节一目了然。再用select char_length(vname) from tablename,你会发现二者的关系就是上述内容。

回到那个问题,这100的长度到底能存多少个中文,既然一个中文占3个字节,是不是就只能存100/3=33个中文呢??换句话说,100这个数字是字节数,还是字符数!?为此我做了如下测试:

在linux上的mysql中定义了下表

CREATE TABLE `test` (

`v` varchar(4) default NULL,

`c` char(4) default NULL

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

即如下图

然后insert into test values (‘围脖你好’,’围脖你好’);有2个warning,select之后才发现

只存进去一个“新”字,后面的全丢了。这就说明,varchar(4)和char(4)中的4是字节数,即100是字节数,只能存33个中文字符。(备注:如果我们存储的字符串长度超过预定义的长度,mysql仍然可以存储成功,只是会提示warning,会将超出的部分自动截断。)

答案貌似明确了,但紧接着问题又来了!

因为以前听说,这个varchar(n)和char(n)中的n指的是存储的字符数,这不和我刚才做的测试完全不符吗?所以我又在本地windows下的mysql中做了同样的操作,建相同的表,插入相同的数据,看到结果,我傻眼了!!

insert into test values (‘围脖你好’,’围脖你好’);并未warning,而是query OK!select之后发现,这四个中文竟然都存进去了,这也就说明我们刚才定义的那个char(4)和varchar(4)中的4是字符数,而非字节数,这么说来,那100就是可以存100个中文字符了,这不完全将刚才的那个结论颠覆了??可是这两个结果都是对的啊,只是环境不同而已。

这样的话,那我们以后定义char和varchar字段还要先判断一下该环境下这个(n)到底代表的啥?是字节还是字符?

不甘心,想搞清楚原因,为何会出现这样的差别?于是yu哥给我说了这样一个命令

Show variable like ‘%char%’;

这下清晰了,linux下的和windows下的mysql相关变量编码定义完美呈现

实际上,character_set_client、character_set_connection、character_set_results是可以改变的,这个可以使用set names gbk/utf8, 只是为了和客户端编码页保持一致,不会乱码,如果客户端编辑页设定的文档是utf8,那么我们自然要set names utf8了,gbk同理。这个命令只会改变显示问题,底部的database的编码还是不会因为这个命令而受到影响的。包括server、system也不会随之改变,这时我们对比上下两张表,他们的server和system以及database的编码发现Linux下的都是Latin1,而windows下的这个都是utf8,

我们知道Latin1都是存储字节为单位的字符比如数字、字母,一个Latin字符只占一个字节,而utf8存储的种类繁多,字符所占的字节数也就不确定了,utf8具有统一功能,其实网上大多是说char(n)存的是n个字符,就是因为此处的编码都是utf8的,utf8屏蔽了中文和英文和数字的显示区别,他们都是一个字符,所以定义的时候那个n就代表了字符的个数,具体占多少个字节是根据他们自身字符串的长度定的,比如char(100)存储100个中文,那么占300个字节,存100个字母,就占100个字节。

但是这好像并不能说明这n代表的是字符而不是字节!

什么情况下它代表字节,什么情况下代表字符?这和我们刚才列出的那些变量的编码有什么关系?。。。。。。继续探索中,求指点!

注:部分描述可能存在问题,望提出宝贵的意见和指导。

附:char与varchar的部分总结比较(与此文无关)

关于char/varchar(n)中n的探究:字符数or字节数的更多相关文章

  1. Java中的字节流,字符流,字节缓冲区,字符缓冲区复制文件

     一:创建方式 1.建立输入(读)对象,并绑定数据源 2.建立输出(写)对象,并绑定目的地 3.将读到的内容遍历出来,然后在通过字符或者字节写入 4.资源访问过后关闭,先创建的后关闭,后创建的先关闭 ...

  2. 用PHP,怎么获取PHP.ini中的文件上传最大的字节数。也就是默认的2M

    PHP中用ini_get函数来获取服务器允许的文件上传最大字节数,如:

  3. ORACLE中一个字符占多少字节?

    问题描述 或许你会说一个中文字符占2个字节,这是一定的?如何计算一个字符串的字节数? 解决方案 在oracle中一个字符特别是中文占几个字节是不同的. 比如我创立一个表create table tes ...

  4. Java中字符编码和字符串所占字节数 .

    首 先,java中的一个char是2个字节.java采用unicode,2个字节来表示一个字符,这点与C语言中不同,C语言中采用ASCII,在大多数 系统中,一个char通常占1个字节,但是在0~12 ...

  5. Python中的字符串与字符编码

    本节内容: 前言 相关概念 Python中的默认编码 Python2与Python3中对字符串的支持 字符编码转换 一.前言 Python中的字符编码是个老生常谈的话题,同行们都写过很多这方面的文章. ...

  6. 【转】Python中的字符串与字符编码

    [转]Python中的字符串与字符编码 本节内容: 前言 相关概念 Python中的默认编码 Python2与Python3中对字符串的支持 字符编码转换 一.前言 Python中的字符编码是个老生常 ...

  7. 数据库中char, varchar, nvarchar的差异

    char     char是定长的,也就是当你输入的字符小于你指定的数目时,char(8),你输入的字符小于8时,它会再后面补空值.当你输入的字符大于指定的数时,它会截取超出的字符.    nvarc ...

  8. MySQL中varchar与char的区别以及varchar(50)中的50代表的涵义

     varchar与char的区别: 1).varchar与char的区别char是一种固定长度的类型,varchar则是一种可变长度的类型 尽可能的使用 varchar 代替 char ,因为首先变长 ...

  9. mysql中char,varchar,text

    1.char char最大长度是255字符,注意是字符数和字符集没关系. 1)可以有默认值, 2)尾部有空格会被截断 3)不管汉字.英文,还是其他编码,都可以存255字符 2.varchar 1)va ...

随机推荐

  1. web qq 获取好友列表hash算法

    web qq 获取好友列表hash算法 在使用web qq的接口进行好友列表获取的时候,需要post一个参数:hash 在对其js文件进行分析之后,发现计算hash的函数位于: http://0.we ...

  2. CentOS和Ubuntu的区别

    CentOS(Community ENTerprise Operating System)是Linux发行版之一,它是来自于Red Hat Enterprise Linux依照开放源代码规定释出的源代 ...

  3. [Python shelve模块Error]bsddb.db.DBPageNotFoundError: (-30986, 'DB_PAGE_NOTFOUND: Requested page not found')

    在用scrapy抓数据,用shelve保存时出现了这个Error,目标是储存一串unicode字符串组成的列表,exception代码是tempbase['joke']=joke_list,测试只要j ...

  4. 纯js实现div内图片自适应大小

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. bower解决js库的依赖管理

    从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎.chrome浏 ...

  6. jquery-1.10.2 获取checkbox的checked属性总是undefined

    项目中用的jquery-1.10.2 需要检测一个checkbox的选中状态,想当然的用 .attr("checked") ,结果发现,无论是否选中,这个值都是 undefined ...

  7. Jasper_sheetName_defined by parameter or hard coding or filed name

    1.根据传递的参数定义sheet name (jasper sheet name defined by parameter) (1) 获取后台参数 <parameter name="P ...

  8. 关于Android界面编程与视图(View)组件

    UI组件--------------->android.widget.* View组件------------->android.view.* 视图(View)组件 所有UI组件都是建立在 ...

  9. Windows 8.1 Update1 6610 32位/64位下载、安装和新增功能简评

    今天,微软已经确认完成Windows 8.1 2014 Update RTM正式版的开发工作,累计修复99%的已知bug.随后,微软会将Win8.1首个春季更新正式版,即Win8.1 2014 Upd ...

  10. 热点块引发的cache buffers cahins latch

    热点块引发的Cache buffer Chains latch: SQL语句即便适当进行了调优,有时也无法解决cache buffers cahins latch,若在编写SQL语句时的SQL工作方式 ...