为什么不使用varchar(max)?

问题描述 投票:69回答:8

在数据库设计方面,我有点老了,所以我完全在列中使用正确的数据大小。但是,在为朋友查看数据库时,我注意到他经常使用varchar(max)。现在,我的想法是把它扔回给他并告诉他改变它。但后来我想到了它并且没有提出他不使用它的充分理由(如果你想知道的话,他会使用案例类型工具来生成数据库)。

我一直在研究varchar(max)用法的主题,我不能真正想出他不使用它的任何理由。

他没有将列用于索引,位于数据库上的应用程序对输入有限制,因此它不允许在字段中使用大量条目。

任何帮助将不胜感激,以帮助我让他看到光:)。

sql tsql sql-server-2008 varcharmax
8个回答
33
投票

我对此的回答,不是关于Max的使用,而是关于VARCHAR(max)vs TEXT的原因。

在我的书中;首先,除非你绝对肯定你永远不会编码除英文文本以外的任何内容,而且人们不会引用外国地名,那么你应该使用NVARCHAR或NTEXT。

其次,这是领域允许你做的事情。

与VARCHAR相比,TEXT很难更新,但您可以获得全文索引和许多聪明的东西。

另一方面,VARCHAR(MAX)有一些模糊性,如果单元格的大小<8000个字符,它将被视为行数据。如果它更大,它将被视为用于存储目的的LOB。因为如果不查询RBAR就无法知道这一点,这可能会为您需要确定数据以及需要花费多少读取数据的地方提供优化策略。

否则,如果您的使用相对平凡,并且您不希望数据大小有问题(您正在使用.Net的IE,因此不必担心您的字符串/ char *对象的大小)那么使用VARCHAR(max)就可以了。


13
投票

有一篇关于为什么不使用varchar max here的博客文章

编辑

基本区别在于存储数据的位置。 SQL数据行的最大大小为8000字节(或者是8K)。然后,2GB varchar(max)无法存储在数据行中。 SQL Server将其“存储在行外”。

因此,由于数据不在磁盘上的相同位置,您可能会受到性能影响,请参阅:http://msdn.microsoft.com/en-us/library/ms189087.aspx


2
投票

如果您在OLTP环境中工作,那么您就可以了解性能。从开销和调优问题到索引限制和查询瓶颈。使用varcahr(max)或任何其他LOB类型很可能违反大多数设计最佳实践,因此除非有特定的业务需求无法通过使用其他类型的键入机制来处理,并且只有varchar(max)适合然后,为什么要让您的系统和应用程序受到其中一种LOB数据类型固有的开销和性能问题?

另一方面,如果您正在OLAP环境或Star Schema DW环境中工作,其中带有描述符字段的Dimension表自然需要详细,那么varchar(max),只要您不将其添加到索引中,可能有用。我仍然建议使用char(x)varchar(x)因为最好只使用这些资源,所以你必须完成工作。


1
投票

除非您期望大量数据,否则不应使用它们,这就是为什么(直接来自联机丛书):

大对象(LOB)数据类型ntext,text,varchar(max),nvarchar(max),varbinary(max),xml或image的列不能指定为索引的键列。

如果您想削弱性能,请将nvarchar用于所有内容。


1
投票

Redgate写了一篇很棒的文章。 https://www.red-gate.com/simple-talk/sql/database-administration/whats-the-point-of-using-varcharn-anymore/

结论

  • 在适当的情况下,使用VARCHAR(n)优于VARCHAR(MAX),以获得良好的设计,如果不是性能优势,并且因为VARCHAR(MAX)数据不压缩
  • 存储大字符串比存储小字符串需要更长的时间。
  • 将行内VARCHAR(MAX)值从低于8,000更新到超过8,000将相对较慢,但单个事务的差异可能无法测量。
  • 将行内VARCHAR(MAX)值从8,000以上更新到8,000以下将比将表设置为在行外存储数据更快。
  • 使用VARCHAR(MAX)的行外选项将导致写入速度变慢,直到字符串很长。

0
投票

我不知道sql server如何从性能,内存和存储角度处理大型(声明的)varchar字段..但是假设它与较小的声明的varchar字段一样有效,那么仍然存在完整性约束的好处。

位于数据库上的应用程序应该对输入有限制,但如果应用程序在这方面存在错误,数据库可以正确报告错误。


0
投票

差异在下一个: VARCHAR(X)可以编入索引并存储在MDF/NDF数据文件中。 VARCHAR(MAX)无法编入索引,因为可以达到高音量,然后将存储为单独的文件,而不是存储在MDF/NDF数据文件中。


0
投票

认为应用程序只会将短字符串传递给数据库,这有点过时了,这样就可以了。

在现代,您必须预期数据库将主要由当前应用程序访问,但可能存在该应用程序的未来版本(该版本的开发人员是否知道将字符串保持在一定长度以下?)

您必须预期将使用Web服务,ETL过程,LYNC到SQL以及任何其他已有的和/或尚未存在的技术来访问您的数据库。

一般来说,我尽量不去看varchar(4000),因为它毕竟是四千个字符。如果我超过了那个,那么我会寻找其他数据类型来存储我想要存储的任何内容。 Brent Ozar写了一些漂亮的great stuff

总而言之,在您开展项目时,评估当前设计对当前需求的方法非常重要。了解各个部分的工作原理,了解各种方法的权衡并解决手头的问题。行使一些伟大的公理会导致盲目坚持,这可能会使你成为一个lemming

© www.soinside.com 2019 - 2024. All rights reserved.