【问题来源】将设计的数据库表展示的时候,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. 织梦dedecms自定义字段在首页列表页文章页的调用

      1.首页调用. {dede:arclist addfields='字段英文名' channelid='模型ID' row='条数' type='栏目ID'}       [field:字段英文名/ ...

  2. php环境安装及搭建

    最近由于项目需要 转战 PHP .  在做了差不多两年java后 说实话看php代码还是有些难受的. 毕竟不习惯.废话不说 先说一下 PHP环境的部署等等,也就是最近几天学习的心得吧.方便以后参考. ...

  3. NPAPI开发常识

    其实,就在几天前,我根本不知道什么是NPAPI插件.因为最近的项目中用到需要在非IE下检测客户端是否安装,最终找到浏览器插件NPAPI. 以下资料来源于网络收集,以此给那些和我一样迷茫的人.本文的目的 ...

  4. [TYVJ] P1001 第K极值

    第K极值   背景 Background 成成第一次模拟赛 第一道    描述 Description 给定一个长度为N(0<n<=10000)的序列,保证每一个序列中的数字a[i]是小于 ...

  5. 使用Discuz!自带参数防御CC攻击以及原理,修改Discuz X 开启防CC攻击后,不影响搜索引擎收录的方法

    这部份的工作,以前花的时间太少. 希望能产生一定的作用. http://www.nigesb.com/discuz-cc-attacker-defence.html http://bbs.zb7.co ...

  6. LeetCode_Triangle

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...

  7. IC封装图片认识(一):BGA

    在上篇文章<常用IC封装技术介绍>第一个提到的IC封装形式就是BGA,全称是Ball Grid Array(球栅阵列结构的PCB),它是集成电路采用有机载板的一种封装法.其具有以下五个特点 ...

  8. VS代码生成工具ReSharper使用手册:配置快捷键

    原文 http://www.cnblogs.com/PHPIDE/archive/2013/05/16/3081783.html VS代码生成工具ReSharper提供了丰富的快捷键,可以极大地提高你 ...

  9. 一道有关球赛队员分配的C++程序题目

    题目描述: 两个球队进行比赛,各出三人.甲队为a,b,c三人,乙队为x,y,z三人.已经抽签决定比赛名单. 有人向队员打听比赛安排的名单.a说他不和x比,c说他不和x,z比,请编程找出三队赛手的名单. ...

  10. Unix/Linux环境C编程入门教程(39) shell命令之系统管理

    df命令 用于检测文件系统的磁盘空间占用和空余情况,可以显示所有文件系统对节点和磁盘块的使用情况.命令的使用格式如下: df  [选项] 常用参数及含义如下表所示. df -a:显示所有文件系统的磁盘 ...