为啥我应该使用 char 而不是 varchar? [复制]

Posted

技术标签:

【中文标题】为啥我应该使用 char 而不是 varchar? [复制]【英文标题】:Why should I use char instead of varchar? [duplicate]为什么我应该使用 char 而不是 varchar? [复制] 【发布时间】:2014-10-25 20:09:18 【问题描述】:

Charvarchar 是 SQL 中的数据类型,就像它们在许多其他语言中一样(所以这个问题可能是多语言的)。

据我了解,不同之处在于,如果我将Char 声明为Char(20),它将分配 20(字节/位)[有人也可以澄清一下吗?现在,我将使用字节。]。然后,如果我只使用 16 个字节,我仍然会为该字段分配四个字节。 (浪费了 4 个字节的内存。)

但是,如果我将 varchar 声明为 varchar(20) 并且只使用 16 个字节,它只会分配 16 个字节。

这肯定更好吗?为什么会有人选择char?是遗留的原因,还是我遗漏了什么?

【问题讨论】:

该死,我没看到。我想知道为什么我问的时候没有出现。至少我有答案了,谢谢! 要回答您的其他问题,Char(20) 将为 20 个字符分配足够的空间。多少空间取决于您使用的字符集,但常规英文文本(latin1 是文档中的示例)每个字符只需要 1 个字节。因此,latin1 字符集中将是 20 个字节,但如果您使用的是非英语语言,则可能会更多。 对于 SQL Servervarchar(n) 总是携带至少 2 个字节的开销 - 所以 varchar(2) 不使用 0-2 个字节 - 而是 2-4 个字节 - 而char(2) always 只使用 2 个字节(例如,对于两个字符的国家/地区代码)。因此,如果您在 varchar(20) 列中存储 16 个字符的文本,它将使用 18 个字节的存储空间 @Jason 讨论必须转移到 nchar/nvarchar 才能相关... 【参考方案1】:

首选 VARCHAR。

在过去存储空间紧张的情况下,空间很重要。如今,磁盘存储很便宜,但 RAM 和 IO 仍然很宝贵。 VARCHAR 对 IO 和缓存友好;它允许您更密集地用数据打包 db 缓冲区缓存,而不是浪费文字“空间”空间,出于同样的原因,空间填充会产生 IO 开销。

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

VARCHAR 几乎总是更可取,因为空格填充要求您了解它并以不同的方式编码。不同的数据库处理它的方式不同。使用 VARCHAR,您知道您的字段仅包含您在其中存储的内容。

十多年来我没有使用 CHAR 设计过架构。

【讨论】:

存储很便宜,但谁在乎呢?这不是浪费磁盘空间。这是关于浪费内存中的 I/O 和宝贵的空间。 (内存虽然也很便宜,但在事后通常比存储空间更难扩展。) 我说“这已经不是原因了”,这是出于历史的原因。虽然我也应该提到 varchar 的最佳缓冲区 / IO 特性,但我没想到。 您今天似乎仍然只关注存储:Nowadays, storage is cheap. 这是一句值得纠正的常见格言。 存储就是存储。当我说存储时,我指的是空间,无论它位于何处。您将其作为磁盘读取,但那是一种存储。诚然,我应该并且会重写它,但在我看来,我在考虑空间。 我们是同行,努力改善彼此的答案,以便 OP(和未来的读者)获得最佳信息。我认为您的原始答案很模糊,并且仍然认为您的 cmets 可能会被视为具有误导性。不要那么防御。附言重新阅读我的第一条评论并考虑“但谁在乎存储成本?”之间的区别。 (这就是我的意思)和“但谁在乎你说什么?” (我相信这就是你的接受方式)。再说一次,不要那么防御。我只是想澄清一下磁盘存储和内存存储之间存在差异。【参考方案2】:

来自Specification

字符[(n)]

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

所以Char(20) 将分配固定的 20 字节空间来保存数据。

用法:

例如,如果您有一个名为 Gender 的列,并且您希望仅将 M 分配给男性 (OR) F 分配给女性,并且您确定该字段/列是非空列。在这种情况下,最好将其定义为CHAR(1) 而不是像

Gender CHAR(1) not null

此外,varchar 类型会带来额外的 2 bytes 开销,如文档中所述。存储大小为输入数据的实际长度+2字节。

char 不是这样。

【讨论】:

投反对票的人:想在投反对票的同时发表评论吗? 不是我,但如果我不得不猜测这是因为您只是反刍文档并没有真正解决主要问题 - 您已经说过,对于性别而言,将其定义为“更好”@ 987654331@,但懒得解释原因。 啊!是的,但我通过举例来解释。用那个例子我的意思是当你早知道尺寸并且尺寸将被固定时,使用char 你还没来得及解释为什么... 我不这么认为,除了 Marc_s 在评论中已经提到的 varchar 类型所带来的开销。

以上是关于为啥我应该使用 char 而不是 varchar? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我应该为 MySQL 中的 varchar 选择 255 以外的任何其他长度?

在 Firebird 中使用 VarChar 或 Char 而不是 Integer 时的性能、空间和其他观察

为啥 varbinary 而不是 varchar [重复]

mysql中 varchar(20)我的数据长度超过了,varchar不是自动增长的吗,为啥他把后面超过的内容给截了。

如何在 django 模型字段中强制执行 char(N) 数据类型而不是 varchar(N)

为啥 CHAR 和 VARCHAR 在 MySQL 中返回相同的长度?