zoukankan      html  css  js  c++  java
  • 浅析char与varchar类型、varchar(100)和varchar(10)的区别、varchar最大长度是多少可以存多少汉字、字符/字节/位之间的关系

    一、varchar(100) 和 varchar(10) 的区别在哪里

      一般初学者会认为,二者占用的空间是一样的。比如说我存储5个char,二者都是实际占用了5个char了【不准确的想法:varchar在实际存储的时候会多一个byte用来存放长度】。

      但是深入一下,设计数据库的时候,二者一样吗?答案是否定的。【至少varchar类型需要在数据之前利用一个或者两个字节来存储数据的长度】并且二者在内存中的操作方式也是不同的

      下面的例子中有体现如现在用户需要存储一个地址信息。根据评估,只要使用100个字符就可以了。但是有些数据库管理员会认为,反正varchar数据类型是根据实际的需要来分配长度的,还不如给其大一点的呢。为此他们可能会为这个字段一次性分配200个字符的存储空间。

    1、存储空间相同,但是对内存的消耗是不同的

      这VARCHAR(100)与VARCHAR(200)真的相同吗?结果是否定的。

      虽然他们用来存储90个字符的数据,其存储空间相同,但是对于内存的消耗是不同的

      对于VARCHAR数据类型来说,硬盘上的存储空间虽然都是根据实际字符长度来分配存储空间的,但是对于内存来说,则不是,其是使用固定大小的内存块来保存值

      简单的说,就是使用字符类型中定义的长度,即200个字符空间。显然,这对于排序或者临时表(这些内容都需要通过内存来实现)作业会产生比较大的不利影响。假设VARCHAR(100)与VARCHAR(200)类型,实际存90个字符,它不会对存储端产生影响(就是实际占用硬盘是一样的)。但是,它确实会对查询产生影响,因为当MySql 创建临时表(SORT,ORDER等)时,VARCHAR会转换为CHAR,转换后的CHAR的长度就是varchar的长度,在内存中的空间就变大了,在排序、统计时候需要扫描的就越多,时间就越久

      所以如果某些字段会涉及到文件排序或者基于磁盘的临时表时,分配VARCHAR数据类型时仍然不能够太过于慷慨。还是要评估实际需要的长度,然后选择一个最长的字段来设置字符长度。如果为了考虑冗余,可以留10%左右的字符长度。千万不能认为其为根据实际长度来分配存储空间,而随意的分配长度,或者说干脆使用最大的字符长度。

    2、char 与 varchar 对产生碎片的区别

      从碎片角度进行考虑,使用CHAR字符型时,由于存储空间都是一次性分配的。为此某个字段的内容,其都是存储在一起的。单从这个角度来讲,其不存在碎片的困扰。而 varchar 可变长度的字符数据类型,其存储的长度是可变的。当其更改前后数据长度不一致时,就不可避免的会出现碎片的问题。故使用可变长度的字符型数据时,数据库管理员要时不时的对碎片进行整理。如执行数据库导出导入作业,来消除碎片。

    3、从长度是否相近考虑使用 char 或 varchar

      考虑其长度的是否相近,如果某个字段其长度虽然比较长,但是其长度总是近似的,如一般在90个到100个字符之间,甚至是相同的长度。此时比较适合采用CHAR字符类型。比较典型的应用就是MD5哈希值。当利用MD5哈希值来存储用户密码时,就非常适和采用CHAR字符类型,因为其长度是相同的。

      另外,像用来存储用户的身份证号码等等,一般也建议使用CHAR类型的数据。

      另外请大家考虑一个问题,CHAR(1)与VARCHAR(1)两这个定义,会有什么区别呢?虽然这两个都只能够用来保存单个的字符,但是VARCHAR要比CHAR多占用一个存储位置。这主要是因为使用VARCHAR数据类型时,会多用1个字节用来存储长度信息。这个管理上的开销char字符类型是没有的。

    4、总结

      二者在磁盘上存储占的空间是一样的,区别有二:

    (1)第一:一个变长,一个固定长度。如果长度相近,尽量使用 char 类型

    (2)第二:在内存中的操作方式,varchar也是按照最长的方式在内存中进行操作的。比如说要进行排序的时候,varcahr(100)是按照100这个长度来进行的。

    (3)使用 varchar 数据类型,会多用 1 个字节来存储长度信息,造成管理上的开销。

    (4)char 不会产生碎片,varchar 会产生碎片,需要碎片整理。

    二、varchar的最大长度是多少

    1、一个字符占多少字节

      具体还是要看版本的,一个字符占用3个字节 ,一个汉字(包括数字)占用3个字节 = 一个字符

      MySQL 4.0版本以下,varchar(100),指的是100字节,如果存放UTF8汉字时,只能存33个(每个汉字3字节)

      MySQL 5.0版本以上,varchar(100),指的是100字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放100个。

      UTF8编码中一个汉字(包括数字)占用3个字节

      GBK编码中一个汉字(包括数字)占用2个字节

    2、varchar 的最大长度是多少,可以存储多少汉字

      mysql 的varchar字段的类型虽然最大长度是65535,但是并不是能存这么多数据,最大可以到65533,其中需要1到2个字节来存储数据长度(如果列声明的长度超过255,则使用2个字节来存储长度,否则1个字节)。当不允许非空字段的时候(因为要用一个字节来存储不可为空的标识),当允许非空字段的时候只能到65532(省下了存储非空的那个字节)。

      行中可以用的字节数如下计算:

    (1)字段非空时候:varchar(65535) -2 bytes (存储长度,按2个算) - 1byte (latin1类型) - 1 (null byte)=65531 字节可以用。减1的原因是实际行存储从第二个字节开始。

    (2)字段可以空时候:varchar(65535) -2 bytes (存储长度,按2个算) - 1byte (latin1类型) =65532 字节可以用。

      根据这个最大字节数,以及编码方式,可以计算能存储的汉字数。

    三、字符、字节、位,之间的关系

    1、位

      数据存储的最小单位。每个二进制数字0或者1就是1个位。

    2、字节

      8个位构成一个字节;即:1 byte (字节) = 8 bit(位);

      1 KB = 1024 B(字节);1 MB = 1024 KB; (2^10 B)1 GB = 1024 MB; (2^20 B)1 TB = 1024 GB; (2^30 B)

    3、字符

      a、A、中、+、*、の……均表示一个字符;一般 utf-8 编码下,一个汉字字符占用 3 个字节;数字属于汉字,和汉字占用一样字节。一般 gbk 编码下,一个汉字字符 占用 2 个 字节;

  • 相关阅读:
    web安全性测试用例
    Postman界面介绍及实例(转)
    基于RFS(robot framework selenium)框架模拟POST/GET请求执行自动化接口测试
    python 将list中的元素按字母排序
    Python操作字典取Key对应的值
    excel的常用工具类
    事务隔离机制
    如何上传附件
    sql函数认识
    对导出poi报表的更深层次了解
  • 原文地址:https://www.cnblogs.com/goloving/p/15027806.html
Copyright © 2011-2022 走看看