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

11
经常建议选择尽可能窄的数据库字段大小。我想知道这在SQL Server 2005 VARCHAR列上适用于什么程度:在VARCHAR(255)字段中存储10个字母的英文单词不会占用比VARCHAR(10)字段更多的存储空间。
还有其他原因限制VARCHAR字段的大小,使其尽可能接近数据大小吗?我在考虑:
- 性能:在选择、过滤和对数据进行排序时,使用较小的n是否有优势? - 内存,包括应用程序方面(C ++)? - 样式/验证:您认为限制列大小以强制非语义数据导入失败(例如200个字符的姓氏)有多重要? - 还有其他吗?
背景:我帮助数据集成商设计流入基于数据库的系统的数据流程。他们必须使用限制其数据类型选择的API。对于字符数据,只有n <= 255的VARCHAR(n)可用; CHAR,NCHAR,NVARCHAR和TEXT不可用。我们正在尝试制定一些“最佳实践”规则,并且问题出现了,即即使对于实际最大大小永远不会超过30个字节左右的数据,使用VARCHAR(255)是否会产生真正的不利影响。
一个表的典型数据量为100万至1000万条记录,最多有150个属性。查询性能(SELECT,经常具有广泛的WHERE子句)和应用程序端检索性能至关重要。

可能还有一个内存使用的好处-请参阅https://stackoverflow.com/a/76991914/819887 - surfmuggle
5个回答

17
  1. 数据完整性 - 这是最重要的原因。如果你创建了一个名为Surname的列,长度为255个字符,你很可能会得到更多的东西,比如名字、姓氏、中间名,或者宠物的名字等等。有人会在这一列中记录笔记或姓氏以外的信息。你想要限制用户只能输入姓氏,所以你需要给这一列设置长度限制。例如,美国纳税人识别号需要9个字符,那么你需要将该列定义为varchar(9),这样其他开发人员就能明白这一列的意图,并避免出现垃圾数据。

  2. 索引和行限制 - 在SQL Server中,你有一个限制为8060字节(如果我没记错的话)。如果你有许多非varchar(max)类型的列并且包含大量数据,那么很快就会超过这个限制。此外,索引的宽度也有一个900字节的限制。因此,如果你想在姓氏列和某些包含大量数据的其他列上创建索引,你可能会超过这个限制。

  3. 报告和外部系统 - 作为报告设计人员,你必须假设如果一个列被声明为最大长度255,它可能有255个字符。如果用户可以这么做,他们就会这么做。因此,仅仅说“它可能不会超过30个字符”并不等同于“它不可能超过30个字符”。永远不要依赖前者。作为报告设计人员,你必须解决用户可能在列中输入大量数据的情况。这意味着要么截断值(如果是这种情况,为什么还要有额外的空间?),要么使用CanGrow创建一个混乱不堪的报告。无论哪种方式,如果列大小与实际存储的数据相差太大,都会让其他开发人员很难理解该列的意图。


3
我认为最大的问题是数据验证。如果你在姓氏字段允许255个字符,那么你的数据库中就可能会出现200多个字符的姓氏。
另一个原因是如果你允许数据库保存255个字符,那么你现在必须在每个涉及到数据库的系统中考虑这种可能性。例如,如果你导出到一个固定宽度的列文件,所有的列都必须是255个字符宽,这可能非常烦人甚至有问题。这只是其中可能引起问题的一个例子。

我也在考虑整体行大小可能会成为一个问题。尽管在SQL Server 2005中允许超过8KB的行,但它是以一种稍微棘手的方式完成的,这可能会影响性能——据我所记,页面本身仍然是8K。因此,如果您在各个地方都使用大列,那么您更容易超过8K页面。还有其他人了解有关性能影响的更多信息吗? - Matt Gibson
是的,如果超过了8060字节的限制,那么最大的可变长度列将被移动到另一个位置,并在原始页面记录中添加指针。只有当可变列的实际大小(而不是声明的大小)将其推到超过8060字节时才会发生这种情况。如果您为几个列分配了VARCHAR(8000),但它们只保存了少量数据,则不会出现该问题。尽管可能会潜在地发生。 - Tom H
非常感谢--您是第一个讨论行长度的人,这是我遗漏的关键信息。我将Thomas的回答标记为“正确”,因为对于未来的读者来说更容易阅读。 - chryss

0
一个好的理由是验证。
例如,在荷兰,社会保障号码始终为9个字符长,如果不允许更多,它就永远不会出现。
如果您允许更多,并且由于某种未知原因有10个字符,您将需要进行检查(否则您不会)以检查其是否为9个字符长。

0

0

1) 可读性和支持

一个数据库开发人员可以查看一个名为StateCode的字段,其长度为varchar(2),并且可以很好地了解该字段保存的数据类型,甚至不用查看内容。

2) 报告

当您的数据没有长度约束时,您希望开发人员强制执行列数据具有相似的长度。如果开发人员未能使列数据一致,则在报告该数据时,这将使数据不一致并且看起来很奇怪。

3) SQL Server数据存储

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

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


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