我意识到,如果我的所有值都是固定宽度的,建议使用CHAR。但是,那又怎样?为了安全起见,为什么不为所有文本字段选择VARCHAR呢?
当前回答
Char更快一点,所以如果你知道一个列有一定的长度,就使用Char。例如,存储(M)ale/(F)emale/(U)nknown表示性别,或者存储2个字符表示美国的一个州。
其他回答
除了性能方面的好处外,CHAR还可以用来表示所有值都应该是相同的长度,例如,美国州缩写的列。
一般规则是,如果所有行的长度接近相同,则选择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个空格时出现了错误。
如果字段中的所有数据值长度相同,则CHAR占用的存储空间比VARCHAR少。现在,在2009年,800GB的数据库与810GB的数据库(如果您将varchar转换为CHARs)在所有用途和目的上是一样的,但对于短字符串(1或2个字符),CHAR仍然是行业的“最佳实践”。
现在,如果您查看大多数数据库提供的各种各样的数据类型,即使是整数(bit、tiny、int、bigint),也有理由选择其中一种。每次都简单地选择bigint实际上是对字段的目的和用途有点无知。如果一个字段只是以年为单位表示一个人的年龄,那么使用bigint就太夸张了。现在它不一定是“错误的”,但它不是有效的。
但这是一个有趣的争论,随着数据库的改进,可以说CHAR vs VARCHAR的相关性越来越小。
在一些SQL数据库中,为了优化偏移量,VARCHAR将被填充到其最大大小,这是为了加速全表扫描和索引。
因此,与CHAR(200)相比,使用VARCHAR(200)并不会节省任何空间。
推荐文章
- GROUP BY with MAX(DATE)
- 删除id与其他表不匹配的sql行
- 等价的限制和偏移SQL Server?
- 为什么我不能在DELETE语句中使用别名?
- 在SQL Server Management Studio中保存带有标题的结果
- "where 1=1"语句
- 如何选择一个记录和更新它,与一个单一的查询集在Django?
- 多语句表值函数vs内联表值函数
- 如何从Oracle的表中获取列名?
- NOLOCK提示在SELECT语句中的作用
- SQL OVER()子句-它什么时候有用,为什么有用?
- 如果字段在MySQL中为空,则返回0
- 我如何使用ROW_NUMBER()?
- SQL或者TSQL是图灵完备的吗?
- 如何检查表上持有哪些锁