将所有Sql Server 2008字符串列varchar(max)都有问题吗?我允许的字符串大小由应用程序管理。数据库应该坚持我给它的东西。通过在Sql Server 2008中将所有字符串列声明为varchar(max)类型,无论实际进入它们的数据大小,我都会受到性能影响吗?
答案 0 :(得分:45)
通过使用VARCHAR(MAX)
,您基本上告诉SQL Server“在此字段中存储您看到的最佳值”,然后SQL Server将选择是将值存储为常规VARCHAR
还是存储为LOB (大型物件) 通常,如果存储的值小于8,000字节,SQL Server会将值视为常规VARCHAR
类型。
如果存储的值太大,则允许该列将页面溢出到LOB页面,就像它们对其他LOB类型(text
,ntext
和{{1}一样。 }) - 如果发生这种情况,则需要额外的页面读取来读取存储在附加页面中的数据(即,存在性能),但是仅当存储的值太大时才会发生。 / p>
事实上,在SQL Server 2008或更高版本中,即使使用固定长度的数据类型(例如image
),数据也可能溢出到其他页面上,但是这些页面称为行溢出数据页面,并且处理方式略有不同。
简短版本:从存储的角度来看,VARCHAR(3,000)
对VARCHAR(MAX)
VARCHAR(N)
使用N
没有任何不利之处。
(请注意,这也适用于其他可变长度字段类型NVARCHAR
和VARBINARY
)
答案 1 :(得分:31)
索引的宽度不能超过900字节。所以你可能永远不会创建一个索引。如果您的数据少于900字节,请使用varchar(900)。
这是一个缺点:因为它给出了
答案 2 :(得分:9)
编辑:Simon有一些关于varchar(max)的帖子。以下评论中的链接显示了这一点。我认为最重要的是http://sqlblogcasts.com/blogs/simons/archive/2009/07/11/String-concatenation-with-max-types-stops-plan-caching.aspx,它讨论了varchar(max)对计划缓存的影响。一般原则是要小心。如果你不需要它是max,那么不要使用max - 如果你需要超过8000个字符,那么确定......去吧。
答案 3 :(得分:5)
对于这个问题,我没有看到提到的几点。
我对why not varchar(8000)
everywhere的回答中提到了其他几个原因。
答案 4 :(得分:4)
答案 5 :(得分:1)
理想情况下,您应该只允许您需要的内容。这意味着如果您确定某个特定列(比如用户名列)的长度永远不会超过20个字符,那么使用VARCHAR(20)和VARCHAR(MAX)可以让数据库优化查询和数据结构。
来自MSDN: http://msdn.microsoft.com/en-us/library/ms176089.aspx
Variable-length, non-Unicode character data. n can be a value from 1 through 8,000. max indicates that the maximum storage size is 2^31-1 bytes.
对于这些列,你真的要接近2 ^ 31-1个字节吗?
答案 6 :(得分:1)
还有另一个原因可以避免在所有列上使用varchar(max)。出于同样的原因,我们使用检查约束(为了避免填充由错误的软件或用户条目引起的垃圾表),我们希望防止任何错误的进程添加比预期更多的数据。例如,如果某人或某事试图在城市字段中添加3,000个字节,我们肯定会知道某些事情是不对的,并且希望停止该过程死在其轨道中以尽早调试它。我们还知道,一个3000字节的城市名称可能无效,如果我们尝试使用它,会导致报告混乱。