【问题来源】将设计的数据库表展示的时候,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. C# 数据实现设计模式

    一个人没事,写了一个底层数据实现读取设计模式,个人觉得还是蛮好扩展,里面有不足的地方希望大家给予指导.话不多说先看个图吧!图可能不正规,伤害了你的眼睛见谅.有图有真相 其实这个设计模式,就是一个简单的 ...

  2. Python网络编程踩的坑

    错误:socket.error: [Errno 10013] 原因:端口号被占用 解决:换其他的端口号或者将其他应用的端口号关闭 错误:File "D:/pyworkspace/homewo ...

  3. Codeforces 474D Flowers

    http://codeforces.com/problemset/problem/474/D 思路:F[i]=F[i-1]+(i>=K)F[i-k] #include<cstdio> ...

  4. libeXosip2(1) -- Modules

    Modules Here is a list of all modules: [detail level 12] The eXtented eXosip stack LibeXosip2 Versio ...

  5. c++ 10

    一.二叉树 1.基本特征 1)树型结构的最简模型,每个节点最多有两个子节点--左子节点和右子节点. 2)单根性,每个子节点有且仅有一个父节点,整棵树有且仅有一个根节点. 3)递归性,以任何一个节点为根 ...

  6. UESTC_排名表 2015 UESTC Training for Graph Theory<Problem I>

    I - 排名表 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit S ...

  7. UVa1587.Digit Counting

    题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=247&p ...

  8. The 4th tip of DB Query Analyzer

    The 4th tip of DB QueryAnalyzer Ma Genfeng (Guangdong Unitoll Services incorporated, Guangzhou 51030 ...

  9. cookielib模块基础学习

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' import cookielib #主要用于处理http客户端的co ...

  10. 【多线程】--生产者消费者模式--Lock版本

    在JDK1.5发布后,提供了Synchronized的更优解决方案:Lock 和 Condition 我们使用这些新知识,来改进例子:[多线程]--生产者消费者模式--Synchronized版本 改 ...