SQL Server:最好使用 varchar(MAX) 还是保留一个单独的注释表和 INNER JOIN 呢?
Posted
技术标签:
【中文标题】SQL Server:最好使用 varchar(MAX) 还是保留一个单独的注释表和 INNER JOIN 呢?【英文标题】:SQL Server: Better to use varchar(MAX) or keep a separate notes table and INNER JOIN it? 【发布时间】:2011-01-27 18:30:50 【问题描述】:我们有一个允许用户输入注释的主记录。每个主要记录有 18 个单独的“注释”字段。
目前我们已经将其规范化为另一个名为 notes 的表,其中包含一个 ID 外键列和一个 varchar(8000) 列,然后我们只需根据需要将它们 INNER JOIN 在一起。我相信这是 SQL Server 2000 中推荐的方法。
我们最近迁移到了具有 varchar(MAX) 的 SQL Server 2008,我们想知道如果我们摆脱单独的注释表并改用 varchar(MAX),性能是否更好或相等。肯定会更方便。
【问题讨论】:
我的理解是 varchar(MAX) 将实际数据保存在单独的页面上,并且仅在实际表中保存指向该位置的指针。换句话说,SQL Server 在内部做着我们手动做的事情。这是不正确的吗?从所有的回复来看,听起来确实如此,但我想澄清一下。这确实是我想知道的问题。 否;这就是text
类型的工作原理。对于varchar(max)
,只有当大小超过varchar
的最大大小(即8000)时才为真。
知道了。谢谢,我相信我现在清楚了。我们将保留它目前的设置。
【参考方案1】:
我对您的设置并不完全清楚...如果您说用户可以输入 18 个单独的注释(可能是不同的“类型”),那么您应该保留辅助注释表。在这种情况下,是的,从 varchar(8000)
切换到 varchar(MAX)
将允许用户在便笺中存储超过 8000 个字符。
为了清楚起见,如果用户正在输入个人注释,那么您应该像现在一样让表格标准化。是否应该从varchar(8000)
切换到varchar(max)
是您是否要允许用户输入超过8000 个字符的问题。请注意,如果这样做,内容将存储在行外,就像您在 2005 年之前的 SQL Server 中使用的 TEXT
类型一样。
如果您说(听起来有点像)用户可以输入一个 large 注释并且您将其动态拆分为多个块,每个块最多 8000 个字符,那么您应该删除第二个表并在父记录上放置一个 varchar(MAX)
列。
这是你要问的吗?
【讨论】:
谢谢。用户实际上正在输入 18 个不同的、单独的注释。我想我不应该提到 8000,因为它确实是一个单独的问题,正如你所提到的。我们将使表格标准化。【参考方案2】:在您的“主”表中包含 varchar(max)
字段是个坏主意,尤其是在您已经对其进行了某种规范化的情况下。
这也会导致页面拆分、碎片化,以及主表的性能非常差。
当有人添加注释时,如果该字段不在该注释表中,则可能会填满数据页并导致其拆分到另一个页面,这就是碎片,即BAD。
【讨论】:
【参考方案3】:更好的设计是保留 Notes 表(您仍然可以通过使用 VARCHAR(MAX) 来增加 Note 的长度,这会导致速度变慢)。
这将允许您将每个音符独立于其他音符视为数据库中的单独实体。
【讨论】:
【参考方案4】:我会建立一个单一的 Note 表,其主键由其父实体的外键和一个音符编号组成,以及一个 [n]varchar(max) 列。这允许您为每个父实体拥有多个注释。
varchar(max) 将在单个常规列中存储多达 8000 个八位字节。如果大小超过该值(最大为 2.1gb),则数据会溢出到溢出页面,就像 [now-deprecated] text/ntext/image 所做的那样。处理文本/blob 数据是一个巨大的麻烦:SQL 现在处理它sotto voce,就像它一样。你得到的只是一个字符串。
【讨论】:
以上是关于SQL Server:最好使用 varchar(MAX) 还是保留一个单独的注释表和 INNER JOIN 呢?的主要内容,如果未能解决你的问题,请参考以下文章
关于SQL Server 2000 Varchar长度的一个问题!!请高手解答
在SQL SERVER中,怎样查询每门功课成绩最好的前两名,帮我写一下,谢谢,请补充: