86

在数据库设计方面我有点老派,所以我完全赞成在列中使用正确的数据大小。但是,在为朋友查看数据库时,我注意到他使用varchar(max)了很多。现在,我的直接想法是把它扔给他并告诉他改变它。但是后来我想了想,找不到一个很好的理由让他不使用它(如果你想知道的话,他使用了一个案例类型的工具来生成数据库)。

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

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

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

4

9 回答 9

39

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

在我的书中;首先,除非您可以绝对确定您永远不会编码除英文文本之外的任何内容,并且人们不会引用外国位置的名称,否则您应该使用 NVARCHAR 或 NTEXT。

其次,这是字段允许您执行的操作。

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

另一方面,VARCHAR(MAX) 有一些歧义,如果单元格的大小 < 8000 字符,它将被视为行数据。如果它更大,它将被视为 LOB 用于存储目的。因为如果不查询 RBAR 就无法知道这一点,这可能对您需要确定数据及其读取次数的地方有优化策略。

否则,如果您的使用相对普通,并且您不希望遇到数据大小问题(即您使用的是 .Net,因此不必担心字符串/char* 对象的大小)然后使用 VARCHAR(max) 就可以了。

于 2011-08-21T21:58:30.327 回答
15

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

编辑

基本区别在于数据的存储位置。SQL 数据行的最大大小为 8000 字节(或者是 8K)。那么一个 2GB 的 varchar(max) 不能存储在数据行中。SQL Server 将其存储为“行外”。

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

于 2011-08-21T22:01:16.807 回答
3

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

另一方面,如果您在 OLAP 环境或 Star Schema DW 环境中工作,其维度表具有自然需要详细的描述符字段然后是 varchar(max),只要您不将其添加到索引中,可能有用。即使这样,我仍然建议使用 char(x) varchar(x) 因为仅使用您绝对必须完成工作的那些资源始终是最佳实践。

于 2015-07-03T04:24:51.730 回答
1

除非您期望有大量数据,否则不应使用它们,原因如下(直接来自联机丛书):

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

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

于 2012-04-11T18:05:38.730 回答
1

为什么不?有理由不使用 varchar(max):

  1. 就像一个好的旧 BLOB 一样,SQL Server不能索引 varchar(max) 列
  2. 过度配置只是浪费和懒惰,特别是 varchar(max) 因为它每行分配至少 8 个字节。我见过开发人员将“max”分配给单字节二进制(True / False)变量,后来才发现系统在使用这些值区分数据时像糖蜜一样慢。
  3. 您无法推断保存在那里的数据类型。明显的用例例外是保存高达 8K 的实际大文本块。
于 2021-12-15T18:07:22.797 回答
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) 值从低于 8,000 更新到超过 8,000 将相对较慢,但单个事务的差异可能无法测量。
  • 将行内 VARCHAR(MAX) 值从超过 8,000 更新到低于 8,000 将比将表设置为存储行外数据更快。
  • 对 VARCHAR(MAX) 使用行外选项将导致写入速度变慢,直到字符串非常长。
于 2018-08-30T16:07:53.723 回答
0

差异在下一个:
VARCHAR(X)可以被索引
VARCHAR(MAX)不能被索引

于 2013-10-31T15:09:00.343 回答
0

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

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

于 2011-08-21T21:58:08.703 回答
0

   相信应用程序只会将短字符串传递给数据库,这有点过时了。

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

   您必须预期 Web 服务、ETL 流程、LYNC 到 SQL 以及任何其他数量的现有和/或尚不存在的技术将用于访问您的数据库。

   一般来说,我尽量不要超过 varchar(4000),因为它毕竟是四千个字符。如果我超过了这个值,那么我会寻找其他数据类型来存储我想要存储的任何内容。 Brent Ozar在这方面写了一些非常棒的东西

综上所述,当你在一个项目上工作时   ,评估当前设计的方法来满足你当前的需求是很重要的。了解各个部分的工作原理,了解各种方法的权衡并解决手头的问题。运用一些伟大的公理可能会导致盲目的坚持,这可能会让你变成一只旅鼠

于 2018-05-02T15:39:59.820 回答