在SQL中,选择使用CHAR而不是VARCHAR的用例是什么?

13 浏览
0 Comments

在SQL中,选择使用CHAR而不是VARCHAR的用例是什么?

我明白如果所有的值都是固定宽度的话,推荐使用CHAR。但是,又怎样呢?为了安全起见,为什么不只选择VARCHAR作为所有文本字段的类型呢?

0
0 Comments

使用CHAR而不是VARCHAR的用例包括:

1. 当所有的值都应该具有相同的长度时,可以使用CHAR,例如用于美国州缩写的列。

2. 当需要区分使用2个字符或3个字符的国家代码缩写时,可以使用CHAR。

如果确实是固定长度的值,那么应该有一个强制约束来实施。尽管使用CHAR,但需要确保约束不会计算填充。为了解决这个问题,可以使用TRIM函数去除填充空格。

以下是一个例子:

CREATE TABLE country (

country_code CHAR(3) NOT NULL,

country_name VARCHAR(50) NOT NULL

);

ALTER TABLE country

ADD CONSTRAINT check_country_code_length

CHECK (LENGTH(TRIM(country_code)) = 2 OR LENGTH(TRIM(country_code)) = 3);

0
0 Comments

CHAR在SQL中选择的用例是什么?

如果你和我一起工作,并且你在使用Oracle,我可能会要求你在几乎所有情况下都使用varchar。假设char使用的处理能力比varchar少,这可能是真的...暂时...但是数据库引擎随着时间的推移会变得更好,这种一般规则可能成为未来的“迷思”。

另外一件事:我从未因为有人决定使用varchar而遇到过性能问题。你将更好地利用你的时间编写好的代码(减少对数据库的调用)和高效的SQL(索引工作原理如何,优化器如何做出决策,为什么exists通常比in快...)。

最后一点想法:我见过各种各样与使用CHAR相关的问题,有人在查找时找到了'',而应该找到' ',或者有人在查找'FOO'时应该找到'FOO(这里有一堆空格)',或者有人没有去除尾部的空格,或者Powerbuilder中的错误导致从Oracle过程返回的值添加了2000个空格。

对于你的第一段我有些不同意见,因为char可能提供一些有用于优化器的提示,甚至是未来的优化器,并且它可以帮助传达列的意图。但是对于你的第三段我表示赞同。我讨厌所有额外的空格。一个字段应该只存储我放进去的内容,不需要额外的填充。基本上,我只在所有数据的长度完全相同的情况下使用char,既不多也不少,现在和将来都是如此。当然,这种情况非常罕见,通常只是char(1)。

char还为分析师和开发人员提供了一些提示...这个东西是x个字符...如果他们考虑以其他格式序列化它,这可能有所帮助。(我被迫在mssql中使用char存储md5校验和,没有uuid类型...而且我从不想要小于32字节的任何内容...还对列施加了限制)。

0
0 Comments

在SQL中,选择CHAR还是VARCHAR有什么用例?

CHAR和VARCHAR的选择基于以下原则:如果所有行的长度接近相同,则选择CHAR。如果长度有较大差异,则选择VARCHAR(或NVARCHAR)。由于所有行的长度相同,因此CHAR可能会更快一些。

根据DB的实现方式而有所不同,但通常,VARCHAR(或NVARCHAR)使用的存储空间会比实际数据多出一到两个字节(用于长度或终止符号)。因此,(假设您使用的是单字节字符集)存储单词“FooBar”的情况如下:

- CHAR(6) = 6个字节(没有额外开销)

- VARCHAR(100) = 8个字节(2个字节的开销)

- CHAR(10) = 10个字节(4个字节的浪费)

对于长度相对相同的数据,CHAR可能更快且更节省空间(在长度差异不超过两个字符的情况下)。

需要注意的是,Microsoft SQL的VARCHAR有2个字节的开销。这可能因DB而异,但通常至少需要1个字节的开销来指示长度或EOL(行尾)。

当涉及到多字节字符集时,情况就不同了,这是VARCHAR变得更好的情况。在VARCHAR中,存储的内容长度和声明的长度没有浪费。

另一个原因是页面拆分和碎片化。我有一个具有IDEN主键的表,由于在varchar列上的页面拆分,导致99%碎片化。这是一个非常活跃的表,并且根据应用程序的性质,新的空行会被创建并填充。而CHAR则可以解决碎片化问题。

这些计算只适用于使用latin1字符集的情况。由于大多数人现在应该使用utf8,所以CHAR列通常使用的空间是VARCHAR的3倍。

如果使用CHAR(100)和VARCHAR(100)来存储字符串"FooBar",结果如下:

- VARCHAR(100) = 8个字节(2个字节的开销)

- CHAR(100) = 100个字节(94个字节的开销)

当使用CHAR时,您在设计时分配了一个固定的字节数。而当使用VARCHAR时,空间分配会随着数据的更改而改变,并且始终有2个字节的开销(用于存储当前变长数据的长度)。

SQL Server使用UCS-2作为其NCHAR和NVARCHAR数据类型,每个字符始终占用两个字节。

需要注意的是,对于MS SQL Server,使用多字节编码的列不会占用更多的字节来分配字符串,而是限制了可以存储的字符数。

在MS SQL Server的官方文档中,指出了一个常见的误解,即CHAR(n)和VARCHAR(n)中的n定义的是字节数,而不是可以存储的字符数。

对于MS SQL Server,可能存在文档错误或者文档不够清晰的情况。否则,为什么要同时存在CHAR和VARCHAR,因为VARCHAR始终比相同长度的CHAR声明占用更多的存储空间。

0