mysql的char,varchar,text,blob是几个有联系但是有有很大区别的字段类型,这算是mysql的基础吧,可是基础没有学好,恶补一下。

先简单的总结一下:

char:定长,最大255个字符

varchar:变长,最大65535个字符(既是单列的限制,又是整行的限制)

text:变长,有字符集的大对象,并根据字符集进行排序和校验,大小写不敏感

blob:变长,无字符集的二进制大对象,大小写敏感

以下只是我个人的理解,才疏学浅,望各路高人指点。

我使用的引擎是myisam,所以以下的探讨是集中在myisam上的。

首先解释char,char是项目中常用的字段类型之一,它代表的含义是采用固定长度存储数据,换句话说,数据初始化的是就为该类型的字段分配固定长度的存储空间,即使没有达到存储空间的长度,实际占用的存储空间也是定义时的长度。举个例子来说,比如某字段 a     char(50),指定的长度是50个字符的存储空间,那么当你存入一个字符:“abc”的时候,实际上字符长度是3个字符,但是占用的硬盘空间还是50个字符。很显然,char的缺点就出来了:浪费存储空间!但是同时char的优点也显示出来了:固定长度,(索引)效率极高,不存在碎片。

这里我们再探讨一下char的存储方式,虽然char会浪费极大的存储空间,但是你想过对于字符串的前后空格char是如何处理的吗?当存储的字符串没有达到char的最大长度时,字符串后面是不会以空格来填充的,而且char会过滤字符串末端的空格然后存储,而在比较字符串的时候又会自动空格填充到字符串的末端。

好了,对char有了了解以后,对varchar的理解也就容易了。

varchar是存储可变长度的字符串,简单的说我们定义表机构的时候指定的字段长度是最大长度,当字符串没有达到最大长度的时候以字符串的实际长度来存储的,不占用多余的存储空间。因此,一般情况下,varchar比char节省存储空间,但是也经常有例外,后面接着探讨这个问题。

一个特殊的情况是创建表的时候采用ROW_FORMAT=FIXED选项(默认的是ROW_FORMAT=DYNAMIC),那么mysql就会为每行数据分配固定长度的存储空间,当然这是特例。不知道你有没有想过:为什么有管理员愿意这样做呢?对varchar分配固定长度的存储空间是有道理的。举一个常见的例子,假设采用DYNAMIC默认选项,那么我们创建一个字段b  varchar(100),现在我们插入一个只有10个字符的数据:abcdefghij,很好,只占用了10个字符的空间,相比char节省了不少存储空间。但是你想到问题了吗?比如某天以后你发现这个字段需要更新一下,更新为20个字符的数据:abcdefghijklmnopqrst,你知道数据库该如何存储吗?原先的存储位置分配的只有10个字符的空间,现在要存储20个字符,小于长度限制(最大长度是100个字符),问题就来了,mysql会如何处理呢?这里接下来可能要探讨mysql存储层面的分页机制或者拆分机制,就不再继续深入了。总之无论mysql采取什么方式,肯定会在磁盘上形成碎片,久而久之形成的磁盘碎片对系统效率是一个致命的打击,所以我们经常看到有管理员要把mysql导出然后导入,就是为了解决这个问题,提高效率。

上面我们提出来了一个问题:varchar比char节省存储空间,但是也经常有例外!对于这个疑问我们如何理解呢?要深入分析这个问题,我们需要再次深入了解varchar的存储机制。常用的中文存储一般采用gbk或者utf-8两种字符集,gbk每个字符占2个字节,utf-8每个字符占3个字节,所以:gbk字符集的最大存储长度是

(65535-1-1)/2= 32766或者(65535-1-2)/2= 32766,这个算法的含义是:65535是varchar的最大长度,第一个-1表示实际存储位置是从第二位开始的,第二个-1或者-2代表的含义是:varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度(长度小于255时用1个字节,长度超过255时需要2个字节),除以2的原因是一个gbk字符集的字符占2个字节长度,所以根据情况可以得出gbk字符集的最大存储长度是32766。

那么UTF-8字符集呢?算法如下:

(65535-1-1)/3=  21844或者(65535-1-2)/3= 21844减1减2的含义同上,除以3的含义是一个utf-8的字符集字符占用实际长度是3个字节。

看完了这段你就能理解char(1)和varchar(1)占用的存储空间了吧?在这个极端情况下,很显然char更节省存储空间,因为char没有管理数据的额外开销。

接下来,我们重点探讨一下varchar的65535存储长度代表的真正含义是什么?因为前面说过一句话:既是单列的限制,又是整行的限制!我们详细来解释一下。对于单列的限制,我们举一个例子:create table tablename(c varchar(N)) charset=gbk;那么N的最大值是(65535-1-2)=32766。同时,如果同一个有其他字段的话,那么所有字段的长度和不能超过65535,举个例子:create table tablename(c1 int(4), c2 char(30), c3 varchar(N) ) charset=utf8,那么N的最大值是(65535-1-2-4-30*3)/3=21812,也许你很理解int(4)需要4个字符的位置,这里可能需要更深入的了解int的存储机制,我不太了解,书还没有看呢。总之int类型占用4个字符的长度,换句话说create table tablename(c1 int(32), c2 char(30), c3 varchar(N) ) charset=utf8,N的最大值也是(65535-1-2-4-30*3)/3=21812。我做了一个简单的实验,看截图。

第一张varchar的长度大于21812,于是失败了

废话了这么多,总之一句话:char在浪费存储空间的劣势下,获得了较高的效率,varchar相反。接下来我们也要总结一下什么情况下使用char,什么情况下使用varchar。

原则一:根据字符串长度确定,凡是固定长度的字符串或者类似固定长度的字符串一律用char。比如身份证号码,手机号码,银行卡号,MD5,哈希值等这是字符串是固定长度的,毫无疑问用char,还有一类是基本固定长度但是略有出入的,比如中国人的姓名等,一般长度可能是2~5个汉字,这类信息也非常适合用char来存储,只要分配一些略大于通常长度即可。

原则二:数据是否经常更改导致碎片,可能经常变动而产生存储碎片的小字符串一律用char。我们知道char类型的数据是一次性分配存储空间的,无论以后你怎么修改,数据始终在该存储空间内的,不会产生碎片。而varchar则不同,varchar的数据长度是可变的,当修改后的数据大于当前存储长度时,就会产生碎片,如果该应用是反复修改数据的应用,那么久而久之就是产生无数碎片,效率可想而知。

原则三:理解varchar的存储空间和内存空间的区别,合理指定varchar的长度。我们知道varchar的存储长度是根据字符串的长度而定的,但是运行时占用的内存空间却是按照定义的长度分配内存空间的(我的理解,不知道是否正确)。这个现象导致存储一个字符串,比如通信地址,通畅在100个字符内就能存储完成,于是varchar(100)是一个合理的选择,但是由于之前讲的,可能有人图方便使用varchar(500),反正用的存储空间是一样的,但是效果确实不一样的。在内存模型中varchar(100)与varchar(500)是两码事,后者比前者占用多5倍的内存空间,在临时表和排序的时候这个差别几乎可能差一个数量级,于是效率可想而知。

基本上解释完char和varchar,这里顺带看看Nchar和Nvarchar是什么?

nvarchar表示可变长度 Unicode 数据,其最大长度为 4,000 字符;nchar表示固定长度的 Unicode 数据,最大长度为 4,000 个字符。

那Nchar和Nvarchar在什么情况下使用呢?我们知道字符 中,英文字符只需要一个字节存储就足够了,但汉字众多,需要两个字节存储,英文与汉字同时存在时容易造成混乱,Unicode字符集就是为了解决字符集这 种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。于是支持多语言的站点应考虑使用 Unicode nchar 或 nvarchar 数据类型以尽量减少字符转换问题。同样的解释还有下面我们要研讨的NText。

下面我们看看text和blob

text分为4种类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT,分别对应不同的长度。text是非二进制字符串,并且需要指定字符集,并按照该字符集进行校验和排序。只能存储纯文本,可以看作是VARCHAR在长度不足时的扩展。

blob也分为4种类型:TINYBLOB,BLOB,mediumblob和LongBlob,分别对应不同的长度,blob存储的是二进制数据,因此无需字符集校验,blob除了存储文本信息外,由于二进制存储格式,所以还可以保存图片等信息,blob可以看作是VARBINARY在长度不足时的扩展。

text和blob的各种类型存储长度,我们用如下的表格表示:

TinyBlob                             最大长度255个字元(2^8-1)  
TinyText                             最大长度255个字元(2^8-1)
Blob                                    最大长度65535个字元(2^16-1)
Text                                    最大长度65535个字元(2^16-1)
MediumBlob                         最大长度 16777215 个字元(2^24-1)
MediumText                         最大长度 16777215 个字元(2^24-1
LongBlob                              最大长度4294967295个字元 (2^32-1)
LongText                              最大长度4294967295个字元 (2^32-1)

好了,到此char,varchar,text,blob内容探讨基本完成了,下面是我再次复习一下有关int型数据的内容,列在这里方便对比。

XML/HTML代码

    1. · TINYINT——一个微小的整数,支持 -128到127(SIGNED),0到255(UNSIGNED),需要1个字节存储
    2. · BIT——同TINYINT(1)
    3. · BOOL——同TINYINT(1)
    4. · SMALLINT——一个小整数,支持 -32768到32767(SIGNED),0到65535(UNSIGNED),需要2个字节存储 MEDIUMINT——一个中等整数,支持 -8388608到8388607(SIGNED),0到16777215(UNSIGNED),需要3个字节存储
    5. · INT——一个整数,支持 -2147493648到2147493647(SIGNED),0到4294967295(UNSIGNED),需要4个字节存储
    6. · INTEGER——同INT
    7. · BIGINT——一个大整数,支持 -9223372036854775808到9223372036854775807(SIGNED),0到18446744073709551615(UNSIGNED),需要8个字节存储
    8. · FLOAT(precision)——一个浮点数。precision<=24用于单精度浮点数;precision在25和53之间,用于又精度浮点数。FLOAT(X)与相诮的FLOAT和DOUBLE类型有差相同的范围,但是没有定义显示尺寸和小数位数。在MySQL3.23之前,这不是一个真的浮点值,且总是有两位小数。MySQL中的所有计算都用双精度,所以这会带来一些意想不到的问题。
    9. · FLOAT——一个小的菜单精度浮点数。支持 -3.402823466E+38到-1.175494351E-38,0和1.175494351E-38 to 3.402823466E+38,需要4个字节存储。如果是UNSIGNED,正数的范围保持不变,但负数是不允许的。
    10. · DOUBLE——一个双精度浮点数。支持 -1.7976931348623157E+308到-2.2250738585072014E-308,0和2.2250738585072014E-308到1.7976931348623157E+308。如果是FLOAT,UNSIGNED不会改变正数范围,但负数是不允许的。
    11. · DOUBLE PRECISION——同DOUBLE
    12. · REAL——同DOUBLE
    13. · DECIMAL——将一个数像字符串那样存储,每个字符占一个字节
    14. · DEC——同DECIMAL
    15. · NUMERIC——同DECIMAL

mysql的char,varchar,text,blob的更多相关文章

  1. mysql中char,varchar,text

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

  2. mysql中char,varchar,text区别总结

    具体对这三种类型的说明不做阐述可以查看mysql帮助文档. char的总结:      char最大长度是255字符,注意是字符数和字符集没关系.可以有默认值,尾部有空格会被截断.varchar的总结 ...

  3. mysql列类型char,varchar,text,tinytext,mediumtext,longtext的比较与选择

    储存不区分大小写的字符数据 TINYTEXT 最大长度是 255 (2^8 – 1) 个字符. TEXT 最大长度是 65535 (2^16 – 1) 个字符. MEDIUMTEXT 最大长度是 16 ...

  4. [Android Pro] sqlite数据库的char,varchar,text,nchar,nvarchar,ntext的区别

    reference : http://blog.csdn.net/xingfeng0501/article/details/7817121 1.CHAR.CHAR存储定长数据很方便,CHAR字段上的索 ...

  5. sqlite数据库的char,varchar,text,nchar,nvarchar,ntext的区别

    1.CHAR.CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充. 2.VAR ...

  6. sqlite数据库的char,varchar,text,nchar,nvarchar,ntext的区别(转)

    sqlite数据库存储table1.CHAR.CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不 ...

  7. 字符串类型:char,varchar,text,enum,set

    字符串类型 1.char 格式:char (M) 2.varchar 格式:varchar (M) [注意]M表示允许的字符串长度[65535].M表示的是字符数,而不是字节数.但是最大长度的使用是按 ...

  8. Mysql 中 char 、varchar 、text的区别

    首先它们的存储方式和数据的检索方式都不一样.数据的检索效率是:char > varchar > text 空间占用方面,就要具体情况具体分析了. char:存储定长数据很方便,CHAR字段 ...

  9. mysql之char、varchar、text对比

    mysql5.0.3以后,n都表示字符数(varchar(n)) 检索效率 char > varchar > text 当varchar长度超过255之后,跟text一致,但是设置varc ...

随机推荐

  1. layui分页

    毕业已经两年,期间经历了很多.一个人欢笑与哭泣,在墙角.在路边.在床上.每天搭乘首班车来到公司,每天无数次反省自己,每天每天再问自己为什么活着. 一.下载并引用css和js 地址:点我 <lin ...

  2. MySQL案例之Timestamp和Datetime

    mysql数据库常用的时间类型有timestamp和datetime,两者主要区别是占用存储空间长度不一致.可存储的时间也有限制,但针对不同版本下,timestamp字段类型的设置需要慎重,因为不注意 ...

  3. linux(centos)设置tomcat开机启动

    方法一: linux 下tomcat开机自启动修改Tomcat/bin/startup.sh 为: export JAVA_HOME=/usr/java/j2sdk1.4.2_08 export CL ...

  4. Surrounded Regions [未完成]

    思路完全一样 AC的代码: class Solution { private: struct Point { int x, y; Point(int _x, int _y):x(_x), y(_y) ...

  5. Going Deeper with Convolutions(Inception v1)笔记

    目录 Abstract Introduction First of All Inception Depth Related Work Motivation and High Level Conside ...

  6. 微软操作系统 Windows Server 2012 R2 官方原版镜像

    微软操作系统 Windows Server 2012 R2 官方原版镜像 Windows Server 2012 R2 是由微软公司(Microsoft)设计开发的新一代的服务器专属操作系统,其核心版 ...

  7. 使用mysli防止sql注入

    自从 php5 推出 mysqli 后就开始不提倡使用 mysql_ 开头的接口了,现在使用 mysql_connet 通常调试的时候会报警告说这个不该用 mysqli 使用起来其实更简单 $url ...

  8. 360网站卫士SQL注入绕过案例一个

    不要以为用了360就可以高枕无忧,直接在netcraft的site_report中找到源站服务器IP,直接SQL脱裤,甚至可获取服务器权限. 存在漏洞的网站: 手工测试存在注入点: 但是网站有360保 ...

  9. Webpack笔记(三)——一款破产版脚手架的开发

    前些天一直在学习入门Webpack,后来尝试了自己搭建一下一个简单的React开发环境,后来就在想可不可以自己写一个简单的脚手架,以免每次搭建一个简单的开发环境都需要自己一个个的配置,这样很麻烦,使用 ...

  10. yii 使用小技巧

    ​1.db组件 'schemaCachingDuration'=>3600, 为什么不起做用? 需要开缓存 2.如何在页面下边显示sql的查询时间,在log组件的routes中加入 array( ...