数据库设计的误区—>CHAR与VARCHAR
字符型字段是数据库表中最常见的字段,而字符型字段又分为定长和变长两种。一般来说,VARCHAR类型用于存储内容长度变化较大的数据,CHAR类型用于存储内容长度没有变化或变化不大的数据。
在数据的内部存储上,一般VARCHAR型字段会使用1或2个字节作为数据的长度描述,数据的后面不含无意义的空格;而CHAR型字段会将数据的结尾以空格填充,直至填满定义的长度。
在数据的操作效率上,UPDATE含有变长字段的变长记录会花费较多时间,而对INSERT、DELETE和SELECT操作则没有明显差别。
在数据的索引和匹配上,VARCHAR型字段会将’张三’和’张三 ‘认为是两项不同的数据,而CHAR则认为它们是等同的。
当CHAR型字段与VARCHAR型字段进行关联时,多数的数据库都是以变长字段作为基准,不对CHAR型字段的尾部空格进行裁剪。因此,VARCHAR(12)中的’张三’和CHAR(12)中的’张三’是不相等的,无法进行直接关联。
通常,对于VARCHAR型字段的处理周期为:获取数据、TRIM数据、存储数据、读取数据、展示数据;而对于CHAR型字段的处理周期为:获取数据、存储数据、读取数据、TRIM数据、展示数据。
从对比中我们可以看出,两者的差别在于TRIM数据的处理位置。实际上两者差别还在于:对于VARCHAR型字段来说,TRIM是必须的,而对于CHAR型字段来说,TRIM则是根据需要可选的。也就是说,总体上讲,VARCHAR型字段的处理过程比CHAR型字段的处理过程复杂,因而效率也就不如CHAR型字段高。
另一方面,在进行字段值相等的判断时,VARCHAR型字段首先比较两个字段值的长度,只有在长度相同的情况下才进一步比较其内容;而CHAR型字段直接进行内容的比较。因此从字段值相等的判断这个角度来看,多数情况下,VARCHAR型字段的效率要高于CHAR型字段。
那么在数据库表的设计时,应该如何选择字段的CHAR和VARCHAR类型呢?我主张的原则是:对于长度变化不大的字段,应该使用CHAR型,而对于长度变化较大的字段,则可以考虑使用VARCHAR。还有一些长度变化较大的字段,由于其记录经常被修改,为提高效率,这类字段也应该使用CHAR型字段。也就是说,应该首选CHAR型。举几个例子来说明:
对于9位的机构编码字段,由于所有编码都是9位填满的,因此应该使用CHAR型,如果使用了VARCHAR型,则不仅浪费了存储空间,也降低了所有处理的效率。
对于身份证号码,由于存在15位与18位的差别,此时可以选择使用VARCHAR字段;但是考虑到15和18之间的变化不大,使用CHAR字段也是可以的。特别是15位身份证号是一个历史遗留问题,后续的数据都将是18位的,因此选用CHAR型字段对将来的效率优势是明显的。
对于家庭住址,由于其长度的差距会较大,而且其所在记录也不会被频繁修改,因此非常适宜用VARCHAR型字段进行存储。
通常情况下,满足下列条件之一,我们就应该使用CHAR:
1.字段值长度不变或变化不大;
2.所在记录会被频繁修改。
掌握了上述原则,我们就可以在数据库表的设计时,通过综合考虑各方面的因素来确定字符型数据的类型。按照上一篇中推荐的“业务键”设计模式,通常作为主键的字段都是长度没有变化或变化不大的字段,如账号、卡号、机构号、身份证号等,应该采用CHAR型;而对于其它非索引字段,可根据其内容及其它因素选用CHAR或VARCHAR。
当我们的数据表与外部系统的数据表关联时,如果对方没有按照我们的规则进行数据库表设计,导致在关联字段上一方使用的是CHAR而另一方为VARCHAR,这时就要仔细斟酌数据的转换方式。
如果双方在关联字段上都没有索引,则将CHAR转为VARCHAR会好一些;如果一方有索引而另一方没有,那么就要把关联的数据类型转换为有索引的那个;如果双方都有索引且都要在操作中使用,那么就将数据记录相对较少的那个转换为相对较多的那个。CHAR转VARCHAR使用TRIM,VARCHAR转CHAR使用CAST。
现在,VARCHAR的滥用是数据库设计中另一个非常严重的现象。在数据库设计时,不对数据进行调研和分析,甚至直接想当然地就把所有字符字段设定为VARCHAR(30),这对应用系统的运行和维护都是非常不利的。不针对字段的特点进行精确的描述,就不便于精确地理解业务模型,随着应用系统功能的不断扩充和升级,整个系统模型就会越来越模糊,直至无法维护,最后只好推翻重来,这个代价是非常大的。
数据库设计的误区—>CHAR与VARCHAR的更多相关文章
- 数据库字段类型中char和Varchar区别
char和varchar区别 char类型:对英文(ASCII)字符占用1个字节,对一个汉字占用2个字节,char存储定长数据很方便,char字段上的索引效率级高,比如定义char(10),那么不论你 ...
- 数据库设计(字段)中的char、varchar、text和nchar、nvarchar、ntext的区别
char.varchar.text和nchar.nvarchar.ntext的区别 1.CHAR.CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数 ...
- 数据库中char和varchar区别
区别: 1)char长度是固定,而varchar长度是可变的: 比如:'abc'对于char(10)表示存储字符将占10个字节(包括7个空字符),而同样varchar(10)只占3个自己长度,10只是 ...
- MySQL之char、varchar和text的设计
最近有表结构设计中出现了varchar(10000)的设计引起了大家的讨论,我们下面就来分析分析. 首先我们先普及一下常识: 1.char(n)和varchar(n)中括号中n代表字符的个数,并不代表 ...
- 数据库中char和varchar的区别
1. char类型的长度是固定的,varchar的长度是可变的. 这就表示,存储字符串'abc',使用char(10),表示存储的字符将占10个字节(包括7个空字符) 使用varchar2(10),, ...
- sqlserver数据库中char、varchar、text与nchar、nvarchar、ntext数据类型使用详解
很多开发者进行数据库设计的时候往往并没有太多的考虑char, varchar类型,有的是根本就没注意,因为存储价格变得越来越便宜了,忘记了最开始的一些基本设计理论和原则,这点让我想到了现在的年轻人,大 ...
- 数据库中char与varchar类型的区别
在建立数据库表结构的时候,为了给一个String类型的数据定义一个数据库的数据库类型,一般参考的都是char或者varchar,这两种选择有时候让人很纠结,今天想总结一下它们两者的区别,明确一下选择塔 ...
- 小谈数据库Char、VarChar、NVarChar差异
1. char 固定长度,最长n个字符. 2. varchar 最大长度为n的可变字符串. (n为某一整数,不同数据库,最大长度n不同) char和varchar区别: ...
- 批量替换数据库中所有用户数据表中字段数据类型为char和varchar到nvarchar的脚本
解决问题:字段类型为char的总是占用指定字节长度(末尾好多空白符号),varchar数据类型长度一个汉字占2个字节,内容存储为中文的字段个人建议全部使用nvarchar. 操作说明:打开SQL Se ...
随机推荐
- Unity3d疑难问题解决
1. 加载 c++ dll 不成功,报这个错: Failed to load 'Assets/Plugins/x86_64/myFile.dll' with error 'The operation ...
- html5中的postMessage解决跨域问题
解决跨域问题的方法有很多,如:图像ping(简单).jsonp(缺点是不能实现跨域post).CROS(CORS的本质让服务器通过新增响应头Access-Control-Allow-Origin,通过 ...
- HDU 5487 Difference of Languages(BFS)
HDU 5487 Difference of Languages 这题从昨天下午2点开始做,到现在才AC了.感觉就是好多题都能想出来,就是写完后debug很长时间,才能AC,是不熟练的原因吗?但愿孰能 ...
- 编译内核启用iptables及netfilter
在Network Packet Filtering Framework(Netfilter)一节中还有两个额外的配置节——Core Netfilter Configuration(核心Netfilte ...
- javascript 函数 add(1)(2)(3)(4)实现无限极累加 —— 一步一步原理解析
问题:我们有一个需求,用js 实现一个无限极累加的函数, 形如 add(1) //=> 1; add(1)(2) //=> 2; add(1)(2)(3) //=> 6; add ...
- 支持持久化的内存数据库-----Redis
一.Redis概述 1.1.什么是Redis Redis是一种高级key-value数据库.它跟memcached类似,不过数据 可以持久化,而且支持的数据类型很丰富.有字符串,链表,集 合和有序集合 ...
- 解决:IE中不能自动选择UTF-8编码的解决方法
IE中不能自动选择UTF-8编码的解决办法 在windows操作系统上使用IE作为浏览器时.常常会发生这样的问题:在浏览使用UTF-8编码的网页时,浏览器无法自动侦测(即没有设定“自动选择”编码格式时 ...
- 全球主流8位MCU芯片详细解剖No.2:英飞凌 XC866 - 全文
[导读] XC866是新型8位微控制器系列(XC800)的第一代系列产品,集成高性能8051核.片内FLASH及功能强大的外设集.此外,XC800系列产品内部集成的片 内振荡器和支持3.3V或5.0V ...
- javascript 函数的基础知识
1. Why JavaScript functions always return a value? I'm taking a course in JavaScript programming, an ...
- (简单) POJ 3087 Shuffle'm Up,枚举。
Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuff ...