我意识到,如果我的所有值都是固定宽度的,建议使用CHAR。但是,那又怎样?为了安全起见,为什么不为所有文本字段选择VARCHAR呢?
当前回答
一般规则是,如果所有行的长度接近相同,则选择CHAR。当长度变化显著时,选择VARCHAR(或NVARCHAR)。CHAR也可能更快一些,因为所有的行都是相同的长度。
它因数据库实现而异,但通常,VARCHAR(或NVARCHAR)除了实际数据之外,还会使用一到两个字节的存储空间(用于长度或终止)。因此(假设您使用的是单字节字符集)存储单词“FooBar”
CHAR(6) = 6字节(无开销) VARCHAR(100) = 8字节(2字节开销) CHAR(10) = 10字节(4字节浪费)
最重要的是,对于相对相同长度的数据(在两个字符长度差以内),CHAR可以更快、更节省空间。
注意:Microsoft SQL对于一个VARCHAR有2个字节的开销。这可能因DB而异,但通常至少需要1个字节的开销来指示VARCHAR上的长度或EOL。
正如Gaven在评论中指出的:当涉及到多字节字符集时,情况会发生变化,在这种情况下VARCHAR会成为更好的选择。
关于VARCHAR声明长度的注意事项:因为它存储了实际内容的长度,所以您不会浪费未使用的长度。因此,在VARCHAR(6)、VARCHAR(100)或VARCHAR(MAX)中存储6个字符使用相同的存储量。阅读更多关于使用VARCHAR(MAX)时的差异。在VARCHAR中声明最大大小以限制存储的容量。
在评论中AlwaysLearning指出Microsoft Transact-SQL文档似乎说的恰恰相反。我认为这是一个错误,或者至少文件不清楚。
其他回答
如果您和我一起工作,并且使用Oracle,我可能会让您在几乎所有情况下都使用varchar。char比varchar使用更少的处理能力的假设可能是正确的…现在……但是随着时间的推移,数据库引擎会变得更好,这种通用规则将成为未来的“神话”。
另一件事:我从未见过因为有人决定使用varchar而导致性能问题。你将更好地利用你的时间来编写好的代码(对数据库的调用更少)和高效的SQL(索引如何工作,优化器如何做出决策,为什么它比通常更快……)
最后一个想法:我在使用CHAR时看到过各种各样的问题,人们在“应该找‘’的时候找‘’,或者人们在应该找‘FOO(这里有一堆空格)’的时候找‘FOO’,或者人们没有去掉后面的空格,或者Powerbuilder在从Oracle过程中返回的值中添加2000个空格时出现了错误。
这是典型的空间与性能的权衡。
在MS SQL 2005中,Varchar(或每个字符需要两个字节的语言,如中文)是可变长度的。如果您在将行写入硬盘后再添加数据,则会将数据定位在与原始行不相邻的位置,并导致数据文件碎片化。这将影响性能。
所以,如果空间不是问题,那么Char格式的性能更好,但如果你想保持数据库的大小,那么varchars格式更好。
当使用varchar值时,SQL Server每行需要额外的2个字节来存储关于该列的一些信息,而如果使用char则不需要 所以除非你
我认为在你的情况下,可能没有理由不选择Varchar。它为您提供了灵活性,正如许多受访者所提到的,现在的性能是这样的,除非在非常特定的情况下,我们普通人(而不是谷歌DBA)不会注意到差异。
当谈到DB类型时,值得注意的一件有趣的事情是sqlite(一个非常受欢迎的迷你数据库,具有相当令人印象深刻的性能)将所有内容作为字符串放入数据库并动态地输入类型。
我总是使用VarChar,通常使它比我可能迫切需要的要大得多。如你所说,为了安全起见,为什么不买50英镑呢?
在计算列值实际所需的大小和为Varchar分配空间时,会有一些小的处理开销,因此如果您确实确定值总是多长,那么最好使用Char并避免命中。
推荐文章
- 如何在Ruby On Rails中使用NuoDB手动执行SQL命令
- 查询JSON类型内的数组元素
- 确定记录是否存在的最快方法
- 获得PostgreSQL数据库中当前连接数的正确查询
- 在SQL选择语句Order By 1的目的是什么?
- 我如何循环通过一组记录在SQL Server?
- 如何在SQL Server中一次更改多个列
- 如何从命令行通过mysql运行一个查询?
- 外键约束可能导致循环或多条级联路径?
- 使用LIMIT/OFFSET运行查询,还可以获得总行数
- 当恢复sql时,psql无效命令\N
- 货币应该使用哪种数据类型?
- 如何选择每一行的列值不是独特的
- 如何改变字符集(和排序)在整个数据库?
- mySQL:: insert到表,数据从另一个表?