我该使用char还是varchar?

3
CharVarchar是SQL中的数据类型,就像在许多其他语言中一样(因此这个问题可以是多语言的)。
据我所了解,区别在于如果我将Char声明为Char(20),它将分配20个字节(或位)[有人能否澄清一下这一点?现在我将使用字节。]。然后,如果我只使用了16个字节,仍然会将4个字节分配给该字段。(浪费了4个字节的内存。)
但是,如果我将varchar声明为varchar(20)并且只使用了16个字节,则只会分配16个字节。
这肯定更好吧?为什么有人选择char?是出于传统原因,还是我漏掉了什么东西?

1
该死,我没看到。我想知道为什么我问的时候它没有出现。至少我有了答案,谢谢! - KidCode
1
回答你的另一个问题,Char(20)将分配足够的空间来容纳20个字符。这取决于你使用的字符集有多少空间,但是对于常规的英文文本(例如文档中的latin1),每个字符只需要1个字节。因此,在latin1字符集中,它将占用20个字节,但如果你使用非英语语言,则可能会更多。 - Jason Baker
对于 SQL Servervarchar(n) 总是带有至少 2 字节的开销,因此 varchar(2) 并未使用 0-2 个字节,而是使用了 2-4 个字节,而 char(2) 则始终只使用 2 个字节(例如用于两字符国家代码)。所以,如果您将 16 个字符的文本存储在 varchar(20) 列中,则会使用 18 个字节的存储空间。 - marc_s
1
@Jason,如果要讨论这个问题的相关性,就必须转向nchar/nvarchar。 - Aaron Bertrand
2个回答

12

倾向使用VARCHAR。

在存储空间较为紧张的古老时代,它对于空间很重要。如今,磁盘存储已经很便宜,但内存和IO仍然宝贵。VARCHAR对于IO和缓存友好;它允许您更加密集地将db缓冲区缓存与数据打包在一起,而不是浪费文字“空间”空间,并且出于相同的原因,空格填充会产生IO开销。

使用CHAR()的优点在于可以减少频繁更新记录时的行链接。当您更新一个字段并且值大于之前分配的值时,记录可能会链接。然而这是可管理的;数据库通常支持在表存储属性上设置“百分比剩余”,以告诉数据库每行预先分配多少额外空间以用于增长。

几乎总是使用VARCHAR更好,因为空格填充要求您注意它并编写不同的代码。不同的数据库处理方式不同。使用VARCHAR,您知道您的字段只包含您存储在其中的内容。

我在过去十年中没有使用CHAR设计过模式。


1
存储空间便宜,但谁在乎呢?这不是关于浪费磁盘空间的问题,而是涉及到浪费I/O和内存中宝贵的空间。(尽管内存也很便宜,但在事后扩展通常比存储空间更加困难。) - Aaron Bertrand
即使在今天,内存空间仍然不便宜,当你不得不在I/O中移动更多的8kb页面时也是如此。因此,我仍然不同意你的前提。 - Aaron Bertrand
你评论中的前提是:“我的意思是空间,无论它在哪里。” - Aaron Bertrand
啊,我想告诉OP,除了编码/逻辑问题外,还有空间/物理问题需要理解。这就是我的意思。我并不打算在回答中过于详细,但那是一个错误。 - codenheim
1
我们是同行,试图改进彼此的答案,以便OP(和未来的读者)得到最佳信息。我认为你最初的回答含糊不清,仍然认为你的评论可能会被误解。不要那么防御。附言重新阅读我的第一条评论,并考虑“但谁关心存储成本?”(这就是我的意思)和“但谁在乎你说什么?”(我相信这就是你的理解方式)之间的区别。再次强调,不要那么防御。我只是想澄清磁盘存储和内存存储之间存在着巨大的区别。 - Aaron Bertrand
显示剩余5条评论

2

来自规范

char[(n)]

长度为n字节的固定长度非Unicode字符数据。n必须是1到8000的值。存储大小为n字节。char的SQL-92同义词是character。

因此,Char(20)将分配固定的20个字节的空间来存储数据。

用法:

例如,如果您有一个名为Gender的列,并且您想要分配像M表示男性(或)F表示女性这样的值,并且您确定字段/列是非空列。在这种情况下,最好将其定义为CHAR(1)而不是

Gender CHAR(1) not null

此外,文档中指出,varchar 类型会额外增加2字节的开销。存储大小为实际输入数据长度+2字节。
而对于char类型则不是这样。

1
不是我,但如果我猜的话,可能是因为你只是重复了文档内容,并没有真正回答主要问题 - 你说对于性别来说将其定义为 CHAR(1) "更好",但却没有解释为什么。 - Aaron Bertrand
啊!是的,但是我通过举例来解释。通过这个例子,我的意思是如果你在早期知道大小并且大小将被固定,那么使用 char - Rahul
2
你仍然没有解释清楚为什么... - Aaron Bertrand
你是指他在你回答后5分钟留下的评论吗?评论不是永久的。而且不要假设你的回答的读者甚至会看到评论,更不用说阅读和理解它了,即使它仍然存在。我不想就这个问题与你争论。你问为什么有人可能会对你的回答投反对票,我已经告诉了你我的观点,你可以根据我给出的信息采取行动,也可以不采取。我不是你需要说服的人。 - Aaron Bertrand
Aaron,感谢你指出这一点。我已经编辑了我的答案以包含这个观点。 - Rahul
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接