sql server数据库中char、nchar、varchar、nvarchar的选择

时间:2022-09-03 11:32:19

    在数据库中,字符型的数据是最多的,可以占到整个数据库的80%以上。为此正确处理字符型的数据,对于提高数据库的性能有很大的作用。

    在字符型数据中,用的最多的就是Char与Varchar两种类型。前面的是固定长度,而后面的是可变长度。

    现在我们需要考虑的是,在什么情况下使用Char字符型数据,什么情况下采用Varchar字符型数据。在这部分内容中,我就跟大家来探讨一下这个话题。

    VARCHAR数据类型可以节省存储空间,提高数据处理的效率。

首先说区别:

   char 类型:

      对英文字符占用1个字节,对一个汉字占用2个字节。

      char 存储定长数据很方便,char 字段上的索引效率极高。

      使用:

          比如定义 char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不够的字符用空格去填。

          因为是固定长度,所以速度效率高。

   nchar类型:

      对每个英文字符都占用2个字节,对一个汉字也占用两个字节,所有的字符都占用2个字节。(这是为了方便与其他多种字符进行转换,如中文,音标等)

   varchar(n):

      n 的值必须介于 1  与  8,000 之间。

   nvarchar(n) :

      n 的值必须介于 1  与  4,000 之间。

    varchar(100)/char(100)能存50个汉字,nvarchar(100)/nchar(100)能存100个汉字

    varchar 类型是可变的——如果 varchar (8) 你只存了一个字母,在内存中只占2个字节

    由于char是以固定长度的,所以它的速度会比varchar快得多!但程序处理起来要麻烦一点,要用trim之类的函数把两边的空格去掉!

区别:

  ①从存储方式上,nvarchar是按字符存储的,而 varchar是按字节存储的;

  ②从存储量上考虑, varchar比较节省空间,因为存储大小为字节的实际长度,而 nvarchar是双字节存储;

  ③在使用上,如果存储内容都是英文字符而没有汉字等其他语言符号,建议使用varchar;含有汉字的使用nvarchar,因为nvarchar是使用Unicode编码,即统一的字符编码标准,会减少乱码的出现几率;

  ④   如果你做的项目可能涉及不同语言之间的转换,建议用nvarchar。

(3)优缺点:

Nvarchar优点:判断字符串的时候可以不需要考虑中英文两种字符的差别,可以避免程序中乱码的问题。

缺点:存储英文字符会增大一倍的存储空间.但是在存储代价已经很低廉的情况下,优先考虑兼容性会给你带来更多好处的,效率没有varchar高。

(4)为什么要用nvarchar?

有n前缀的,n表示Unicode字符,即所有字符都占两个字节,nchar,nvarchar

字符中,英文字符只需要一个字节存储就足够了,但汉字众多,需要两个字节存储,英文与汉字同时存在时容易造成混乱,Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。

(5)有关var的简单介绍:

有var前缀的,表示是实际存储空间是变长的,varchar,nvarchar

所谓定长就是长度固定的,当输入的数据长度没有达到指定的长度时将自动以英文空格在其后面填充,使长度达到相应的长度;而变长字符数据则不会以空格填充,比较例外的是,text存储的也是可变长。

(6)如何使用这些类型?

    如果你肯定存储的数据长度,而且不包中文的,可以选择char类型。

    如果肯定存储的数据长度,但可能包括中文,可以选择nchar类型。

    如果不确定存储的数据长度,存储只有英文、数字的最好用varchar

    如果不确定存储的数据长度,也有可能有中文,可以选择nvarchar类型,在SQL Server2005中也是比较常用的字符数据类型。

  在字符长度一定时char的相关性能比varchar好,而在长度不确定时,char类型的字段在使用时性能略差。

  由于char是以固定长度的,所以它的速度会比 varchar快得多(这里说的很粗糙,增删改是哪个速度)!但程序处理起来要麻烦一点,要用trim之类的函数把两边的空格去掉!

  varchar比char节省空间,在效率上比char会稍微差一些,即要想获得效率,就必须牺牲一定的空间,这也就是我们在数据库设计上常说的‘以空间换效率’。

  varchar 虽然比char节省空间,但是如果一个varchar列经常被修改,而且每次被修改的数据的长度不同,这会引起‘行迁移’(Row Migration)现象,而这造成多余的I/O,是数据库设计和调整中要尽力避免的,在这种情况下用char代替varchar2效果会更好一些。

    <反复的修改,优化,整理的简洁、明了一些>

如何选择:

    我们知道VARCHAR数据类型是一把双刃剑,其在带来性能提升的同时,也可能会存在着一些额外的消耗。我们在评估到底是使用VARCHAR数据类型还是采用CHAR数据类型时,就需要进行均衡。在实际项目中,我们会考量如下情况。

    一是根据字符的长度来判断。如某个字段,像人的名字,其最长的长度也是有限的。如我们给其分配18个字符长度即可。此时虽然每个人的名字长度有可能不同,但是即使为其分配了固定长度的字符类型,即18个字符长度,最后浪费的空间也不是很大。而如果采用NVARCHAR数据类型时,万一以后需要改名,而原先的存储空间不足用来容纳新的值,反而会造成一些额外的工作。在这种情况下,进行均衡时,会认为采用CHAR固定长度的数据类型更好。在实际项目中,如果某个字段的字符长度比较短此时一般是采用固定字符长度。

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

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

    四是即使使用Varchar数据类型,也不能够太过于慷慨。这是什么意思呢?如现在用户需要存储一个地址信息。根据评估,只要使用100个字符就可以了。但是有些数据库管理员会认为,反正Varchar数据类型是根据实际的需要来分配长度的。还不如给其大一点的呢。为此他们可能会为这个字段一次性分配200个字符的存储空间。这VARCHAR(100)与VARCHAR(200)真的相同吗?结果是否定的。虽然他们用来存储90个字符的数据,其存储空间相同。但是对于内存的消耗是不同的。这对于排序或者临时表(这些内容都需要通过内存来实现)作业会产生比较大的不利影响。所以如果某些字段会涉及到文件排序或者基于磁盘的临时表时,分配VARCHAR数据类型时仍然不能够太过于慷慨。还是要评估实际需要的长度,然后选择一个最长的字段来设置字符长度。如果为了考虑冗余,可以留10%左右的字符长度。千万不能认为其为根据实际长度来分配存储空间,而随意的分配长度,或者说干脆使用最大的字符长度。

char与varchar的比较:

    下面是使用char与varcahr的一些结果。

   (1)数据存储开销。

      a. 每个varchar列需要额外的两个字节,用于反映存储的数据的长度。

      b. 每个可为NULL的char列,需要一些字节(空位图)来反应数据的为空性。

      c. 无论实际数据的长度是多少,char按照定义的长度分配存储空间。

    (2) NULL值。

      a. char列的NULL值占用存储空间。

      b. varcahr列的NULL值不占用存储空间。

      c. 插入同样数量的NULL值,varchar列的插入效率明显高出char列。

    (3) 插入数据。

      无论插入数据涉及的列是否建立索引,char的效率都明显低于varchar。

    (4) 更新数据

      如果更新的列上未建立索引,则char的效率低于varchar,差异不大;建立索引的话,效率差异较大。

   (5) 修改结构

      a. 无论增加或是删除的列的类型是char还是varchar,操作都能较快的完成,而且效率上没有什么差异。

      b. 对于增加列的宽度而言,char与varchar有非常明显的效率差异,修改varcahr列基本上不花费时间,而修改char列需要花费很长的时间。

   (6) 数据检索。

      无论是否通过索引,varchar类型的数据检索略优于char的扫描。

选择char还是选择varchar的建议:

    (1) 适宜于char的情况:

      a. 列中的各行数据长度基本一致,长度变化不超过50字节;

      b. 数据变更频繁,数据检索的需求较少。

      c. 列的长度不会变化(修改char类型列的宽度的代价比较大)

      d. 列中不会出现大量的NULL值。

      e. 列上不需要建立过多的索引(过多的索引对char列的数据变更影响较大)

   (2) 适宜于archar的情况:

       a. 列中的各行数据的长度差异比较大。

      b. 列中数据的更新非常少,但查询非常频繁。

       c. 列中经常没有数据,为NULL值或为空值。

sql server数据库中char、nchar、varchar、nvarchar的选择的更多相关文章

  1. sql server数据库中char&comma;varchar&comma;nvarchar字段的区别

    Char,varchar,nvarchar字段是sql server数据库中的三种字段类型.好多人在选择存储的时候不知道如何抉择,我给大家讲下这个三个字段类型的区别. Char(n)是长度为n个字节的 ...

  2. C&num;同步SQL Server数据库中的数据--数据库同步工具&lbrack;同步新数据&rsqb;

    C#同步SQL Server数据库中的数据 1. 先写个sql处理类: using System; using System.Collections.Generic; using System.Dat ...

  3. SQL Server 数据库中的几个常见的临界值

    本文出处:http://www.cnblogs.com/wy123/p/6709520.html 1,SQL语句或者存储过程的最大长度(SQL字符串容量)是多少? 经常有人问,我的SQL语句是拼凑出来 ...

  4. char nchar varchar nvarchar的区别&lpar;转)

    char nchar  varchar nvarchar的区别   今天在论坛里看到有人激烈讨论这几个数据类型的区别跟实际使用情况,很多人都搞不清楚究竟哪个场景使用哪个数据类型 现在就摘录一下sql2 ...

  5. 转:SQL SERVER数据库中实现快速的数据提取和数据分页

    探讨如何在有着1000万条数据的MS SQL SERVER数据库中实现快速的数据提取和数据分页.以下代码说明了我们实例中数据库的“红头文件”一表的部分数据结构: CREATE TABLE [dbo]. ...

  6. SQL server数据库中的DateTime类型出现的问题

    我们知道这个SQL server数据库中的DateTime类型是数据库应用开发中经经常使用到的一种数据类型.而C#语言中也有DateTime类型,尽管二者都是用来描写叙述时间的,可是它们的默认值是不同 ...

  7. 浅析SQL Server数据库中的伪列以及伪列的含义

    SQL Server中的伪列 下午看QQ群有人在讨论(非聚集)索引的存储,说,对于聚集索引表,非聚集索引存储的是索引键值+聚集索引键值:对于非聚集索引表,索引存储的是索引键值+RowId,这应该是一个 ...

  8. 清空SQL Server数据库中所有表数据的方法&lpar;转&rpar;

    清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入 ...

  9. &period;NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常)

    .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常) 前段时间项目使用一次性读去SQL Server中保存的电子文件的文件流然后返回给客户端保存下载电子文件, ...

随机推荐

  1. jQuery可拖拽3D万花筒旋转特效

    这是一个使用了CSS3立体效果的强大特效,本特效使用jQuery跟CSS3 transform来实现在用户鼠标按下拖动时,环形图片墙可以跟随鼠标进行3D旋转动画. 效果体验:http://hovert ...

  2. Alpha版本十天冲刺——Day 5

    站立式会议 会前小侃:今天是双11,也是恰逢组内秋鑫同学生日,本组同学祝他双11生日快乐.天气好冷,注意保暖. 会议总结 队员 今天完成 遇到的问题 明天要做 感想 鲍亮 json数据解析学习,完成注 ...

  3. 文字超出DIV的边框

    已经给div设置了高宽,但是文字还是会戳出div而不是换行 鼓捣了一下好像是因为这个原因 如果全是 aaaaaaaaaaaaaaaaaaaaa 这样的纯英文,那么测试的时候是不会换行的,因为浏览器认为 ...

  4. Centos6&period;4 NFS的安装与配置

    NFS,是Network File System的简写,即网络文件系统.网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS. NFS允许一个系统在网络上与他人共享目录和文件.通过使用N ...

  5. 【转】web&period;xml中的contextConfigLocation在spring中的作用

    一.spring中如何使用多个xml配置文件 1.在web.xml中定义contextConfigLocation参数,Spring会使用这个参数去加载所有逗号分隔的xml文件,如果没有这个参数,sp ...

  6. sqlalchemy基础教程

    一.基本配置 连接数据库 外部连接数据库时,用于表名数据库身份的一般是一个URL.在sqlalchemy中将该URL包装到一个引擎中,利用这个引擎可以扩展出很多ORM中的对象. from sqlalc ...

  7. RWCString 定义 memeroy leak

    代码截取片段: testDefs.hh class testDefs { public: static const RWCString testStr; }; testDefs.cc const RW ...

  8. Android&period;StructureOfAndroidSourceCodeRootTree

    Refference 1. How to understand the directory structure of android root tree? http://*.c ...

  9. cocos2dx游戏--欢欢英雄传说--为敌人添加移动和攻击动作

    这里主要为敌人添加了一个移动动作和攻击动作.移动动作是很简略的我动他也动的方式.攻击动作是很简单的我打他也打的方式.效果:代码: #ifndef __Progress__ #define __Prog ...

  10. Hive之GROUP BY详解

    一,GROUP BY 执行理解 先来看下表1,表名为test: 表1 执行如下SQL语句: SELECT name from test GROUP BY name ;   你应该很容易知道运行的结果, ...