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

时间:2020-03-05 18:52:26  来源:igfitidea点击:

我意识到,如果我所有的值都是固定宽度,则建议使用CHAR。但是,那又如何呢?为了安全起见,为什么不为所有文本字段选择VARCHAR?

解决方案

回答

Char快一点,因此如果我们知道的列长度一定,请使用char。例如,存储性别已知的(M)ale /(F)emale /(U)n,或者存储美国州的2个字符。

回答

在计算列值的实际所需大小并为Varchar分配空间时,会产生一些小的处理开销,因此,如果我们确定该值将始终保留多长时间,则最好使用Char并避免命中。

回答

使用varchar值时,SQL Server每行需要额外的2个字节来存储有关该列的某些信息,而如果使用char,则不需要
所以除非你

回答

如果所有行的长度接近相同,通常选择CHAR。当长度变化很大时,请选择VARCHAR。由于所有行的长度相同,因此CHAR也可能会快一些。

它因数据库的实现而异,但是通常VARCHAR除了实际数据外还使用一个或者两个以上的字节存储空间(用于长度或者终止)。因此(假设我们使用的是一个字节的字符集),则存储单词" FooBar"

  • CHAR(6)= 6个字节(无开销)
  • VARCHAR(10)= 8个字节(2个字节的开销)
  • CHAR(10)= 10个字节(4个字节的开销)

底线是CHAR对于相对相同长度(两个字符的长度差异以内)的数据可以更快,更节省空间。

注意:Microsoft SQL有2个字节的VARCHAR开销。这可能因数据库而异,但通常至少需要1个字节的开销才能指示VARCHAR上的长度或者EOL。

正如Gaven在评论中指出的那样,如果我们使用的是多字节可变长度字符集(如UTF8),则CHAR将存储存储字符数所需的最大字节数。因此,如果UTF8最多需要3个字节来存储字符,那么即使仅存储latin1字符,CHAR(6)也将固定为18个字节。因此,在这种情况下,VARCHAR成为更好的选择。

回答

我支持吉姆·麦基思的评论。

此外,如果表只有CHAR列,则索引编制和全表扫描的速度会更快。基本上,如果优化器仅具有CHAR列,则优化器将能够预测每个记录的大小,同时它需要检查每个VARCHAR列的大小值。

此外,如果将VARCHAR列更新为大于其先前内容的大小,则可能会强制数据库重建其索引(因为我们已强制数据库将记录物理移动到磁盘上)。当使用CHAR列时,这将永远不会发生。

但是除非表很大,否则我们可能不会在意性能下降。

记住Djikstra的明智话。早期的性能优化是万恶之源。

回答

在某些SQL数据库中,VARCHAR将被填充到其最大大小以优化偏移量,这是为了加快全表扫描和索引的速度。

因此,与CHAR(200)相比,使用VARCHAR(200)不会节省任何空间

回答

早期的性能优化与使用最佳实践类型的规则之间是有区别的。如果要创建新表,在该表中始终具有固定长度的字段,则使用CHAR是有意义的,在这种情况下,我们应该使用它。这不是早期的优化,而是实施经验法则(或者最佳实践)。

即,如果我们有2个字母的状态字段,请使用CHAR(2)。如果我们有一个带有实际状态名称的字段,请使用VARCHAR。

回答

如果我们正在与我合作,并且正在与Oracle合作,那么我可能会让我们在几乎每种情况下都使用varchar。假设" char"比" varchar"使用更少的处理能力可能是正确的……暂时……但是随着时间的流逝,数据库引擎会变得更好,而这种一般规则将成为未来的"神话"。

另一件事:我从未见过性能问题,因为有人决定使用varchar。我们将可以更好地利用时间编写良好的代码(对数据库的调用更少)和高效的SQL(索引如何工作,优化程序如何制定决策,为什么"存在"比"通常"中的速度更快)。 。

最后的想法:我已经看到使用CHAR时会遇到各种问题,人们在应该寻找""时寻找"",或者在人们应该寻找" FOO"时寻找" FOO"的人们此处),或者不修剪尾随空格的人,或者是Powerbuilder的错误,将总计2000个空格添加到从Oracle过程返回的值上。

回答

除性能优势外,``CHAR''还可用于指示所有值都应具有相同的长度,例如,用于美国州缩写的列。

回答

我会选择varchar,除非该列存储固定值,例如美国州代码-始终为2个字符,并且有效的美国州代码列表不会经常更改:)。

在其他所有情况下,即使像存储哈希密码(固定长度)一样,我也会选择varchar。

为什么-char类型的列总是用空格填充,这使得my_column列定义为char(5),其内部比较值为:'ABC':

my_column = 'ABC' -- my_column stores 'ABC  ' value which is different then 'ABC'

错误的。

此功能可能会在开发过程中导致许多令人讨厌的错误,并使测试更加困难。

回答

有一些性能上的好处,但是这里没有提到:行迁移。使用char可以预先保留整个空间,因此假设我们有一个char(1000),并且存储了10个字符,则将用完所有1000个字符。在varchar2(1000)中,我们将仅使用10个字符。当我们修改数据时,问题就来了。假设我们将列更新为现在包含900个字符。当前块中可能没有扩展varchar的空间。在这种情况下,DB引擎必须将该行迁移到另一个块,并在原始块中创建一个指向新块中新行的指针。要读取此数据,数据库引擎现在必须读取2个块。
没有人可以明确地说varchar或者char更好。有时间权衡的空间,并考虑是否要更新数据,尤其是在很有可能增长数据的情况下。

回答

这是经典的空间与性能的权衡。

在MS SQL 2005中,Varchar(对于每个字符需要两个字节(即中文)的劳格斯语,则为NVarchar)是可变长度的。如果在将数据写入硬盘后添加到该行中,它将在不连续的位置将数据定位到原始行,并导致数据文件碎片化。这会影响性能。

因此,如果空间不是问题,那么Char的性能会更好,但是如果我们想减小数据库的大小,那么varchars会更好。

回答

我认为在情况下,可能没有理由不选择Varchar。它为我们提供了灵活性,正如许多受访者所提到的那样,现在的表现是如此出色,除非在非常特殊的情况下,我们的凡人(与Google DBA相对)不会注意到两者之间的差异。

当涉及到DB Types时,一个值得注意的有趣事情是sqlite(一种性能非常出色的流行小型数据库)将所有内容以字符串和类型的形式实时存储到数据库中。

我总是使用VarChar,通常使它比我可能需要的大得多。例如。正如我们所说,"姓氏"为50,为什么不仅仅为了安全起见。

回答

许多人指出,如果我们知道使用CHAR的值的确切长度会有一些好处。但是,尽管今天将CHAR(2)存储在美国各州非常棒,但是当我们从销售中得知"我们刚刚在澳大利亚进行了首次销售"时,我们就处于痛苦中。我总是高估我认为字段将需要多长时间,而不是做出"准确"的猜测来涵盖将来的事件。 VARCHAR将在这方面给我更多的灵活性。

回答

如果我们在该字段中的所有数据值都具有相同的长度,则CHAR会比VARCHAR占用更少的存储空间。现在,也许在2009年,如果将VARCHAR转换为CHAR,则800GB的数据库在所有意图和用途上都与810GB相同,但是对于短字符串(1个或者2个字符),CHAR仍然是业界"最佳实践"。

现在,如果我们查看大多数数据库提供的各种各样的数据类型,即使仅是整数(bit,tiny,int,bigint)也可以提供,那么就有理由选择一个。每次简单地选择bigint实际上实际上是对该领域的目的和用途的了解。如果一个字段仅代表一个人的年龄(岁),那么bigint就是过大的杀伤力。现在,它不一定是"错误的",但是效率不高。

但这是一个有趣的论点,并且随着数据库的不断改进,可以说CHAR与VARCHAR的相关性降低了。