为什么要使用较短的VARCHAR(n)字段?

时间:2010-06-11 14:41:55

标签: sql sql-server types

经常建议选择尽可能窄的数据库字段大小。我想知道这适用于SQL Server 2005 VARCHAR列的程度:在VARCHAR(255)字段中存储10个字母的英文单词不会占用比VARCHAR(10)字段中更多的存储空间。< / p>

是否还有其他原因限制VARCHAR字段的大小尽可能贴近数据大小?我在考虑

  • 性能:在选择,过滤和排序数据时使用较小的n是否有优势?
  • 内存,包括在应用程序端(C ++)?
  • 样式/验证:您认为限制colunm大小以强制非敏感数据导入失败(例如200个字符的姓氏)有多重要?
  • 还有别的吗?

背景:我帮助数据集成商将数据流设计流入数据库支持的系统。他们必须使用限制他们选择的数据类型的API。对于字符数据,只有{&lt; = 255的VARCHAR(n)可用; CHARNCHARNVARCHARTEXT不是。我们正在尝试制定一些“良好做法”规则,如果使用VARCHAR(255)即使对于实际最大大小永远不会超过30个字节左右的数据,也会产生真正的不利问题。

一个表的典型数据量是1-10 Mio记录,最多150个属性。查询性能(SELECT,通常有广泛的WHERE子句)和应用程序端检索性能是最重要的。

5 个答案:

答案 0 :(得分:13)

  1. 数据完整性 - 到目前为止最重要的原因。如果您创建一个名为Surname的列为255个字符,那么您可能会获得的不仅仅是姓氏。你会得到名字,姓氏,中间名。你会得到他们最喜欢的宠物。你会得到“会计部门的Alice和三角形的头发”。简而言之,您将使用户可以轻松地将该列用作notes / surname列。您希望上限阻止尝试将除姓氏之外的内容放入该列的用户。如果您有一个要求特定长度的列(例如,美国税收标识符为九个字符),但该列为varchar(255),则其他开发人员会想知道您可能会获得的内容废话数据。

  2. 索引和行限制。在SQL Server中,您的IIRC限制为8060字节。有大量数据的大量非varchar(max)列很快就会超出该限制。此外,索引的宽度为IIRC,上限为900字节。因此,如果您想对您的姓氏列和其他包含大量数据的列进行索引,则可能会超出此限制。

  3. 报告和外部系统。作为报表设计者,您必须假设如果声明列的最大长度为255,则可以包含255个字符。如果用户可以这样做,他们就会这样做。因此,要说“它可能不会有超过30个字符。”甚至与“它不能超过30个字符”相同。永远不要依赖前者。作为报表设计者,您必须解决用户将大量数据输入列的可能性。这要么意味着截断值(如果是这样的话,为什么还有额外的空间可用?)或者使用CanGrow来制作一个可爱的报告。无论哪种方式,如果列的大小与存储的实际数据相距甚远,你就会让其他开发人员更难理解列的意图。

答案 1 :(得分:3)

我认为最大的问题是数据验证。如果您为姓氏允许255个字符,您将获得数据库中200多个字符的姓氏。

另一个原因是,如果您允许数据​​库保存255个字符,则现在必须在触及数据库的每个系统中考虑这种可能性。例如,如果您导出到固定宽度的列文件,则所有列的宽度必须为255个字符,这可能非常烦人甚至有问题。这只是一个可能导致问题的例子。

答案 2 :(得分:0)

一个很好的理由是验证。

(例如)在荷兰,社会安全号码总是9个字符长,当你不允许更多它永远不会发生时。

如果您允许更多,并且由于某些未知原因,有10个字符,您将需要检查(否则您不会)检查它是否为9长。

答案 3 :(得分:0)

另一件事是单行数据限制为8060字节,SQL Server使用varchar字段的最大长度来确定这一点。

参考:http://msdn.microsoft.com/en-us/library/ms143432.aspx

答案 4 :(得分:0)

1)可读性&amp;支撑

数据库开发人员可以查看名为StateCode的字段,其长度为varchar(2),并且可以很好地了解该字段所包含的数据类型,甚至无需查看内容。

2)报告

当您的数据没有长度约束时,您希望开发人员强制列数据的长度相似。在报告该数据时,如果开发人员未能使列数据保持一致,那将导致报告数据不一致&amp;看起来好笑。

3)SQL Server数据存储

SQL Server将数据存储在8k“页面”上,从性能角度来看,尽可能高效地存储数据并在页面上存储尽可能多的数据是理想的。

如果您的数据库设计为将每个字符串列存储为varchar(255),则“错误”数据可能会滑入其中一个字段(例如,状态名称可能会滑入StateCode字段,该字段的长度为2个字符),并导致不必要的&amp;低效的页面和索引拆分。