在SQL Server 2005中,将所有字符字段设置为nvarchar(MAX)而不是显式指定长度(例如nvarchar(255))有什么缺点吗?(除了不能在数据库级别限制字段长度之外)


当前回答

截至SQL Server 2019, NVARCHAR(MAX)仍然不支持SCSU“Unicode压缩”-即使使用行内数据存储存储。SCSU是在SQL Server 2008中添加的,适用于任何ROW/ page压缩的表和索引。

因此,即使没有存储在LOB中,具有相同文本内容的NVARCHAR(1..4000)字段所占用的物理磁盘空间也是NVARCHAR(1..4000)字段的两倍。非scsu浪费取决于所表示的数据和语言。

Unicode压缩实现:

SQL Server使用Unicode标准压缩方案(SCSU)算法的实现来压缩存储在行或页压缩对象中的Unicode值。对于这些压缩对象,对nchar(n)和nvarchar(n)列的Unicode压缩是自动的[并且从未对nvarchar(max)使用]。

另一方面,PAGE压缩(自2014年以来)仍然适用于NVARCHAR(MAX)列,如果它们被写入行内数据。所以缺乏SCSU感觉就像“缺少优化”。与SCSU不同,基于共享前导前缀(例如。重复的值)。

然而,使用NVARCHAR(MAX)可能仍然“更快”,即使使用OPENJSON这样的函数会有更高的IO成本,因为它避免了隐式转换。这是一种隐式转换开销,它取决于使用的相对成本,以及字段是在过滤之前还是过滤之后被处理的。在VARCHAR(MAX)列中使用2019年的UTF-8排序规则时也存在同样的转换问题。

使用NVARCHAR(1-4000)也需要N*2个字节的~8000字节行配额,而NVARCHAR(MAX)只需要24个字节。总体设计和使用需要一起考虑,以考虑具体的实现细节。

+在我的数据库/数据/模式中,通过使用两列(读时合并),可以减少40%的磁盘空间使用,同时仍然支持溢出的文本值。SCSU虽然存在缺陷,但它是一种非常聪明且未得到充分利用的存储Unicode的更有效空间的方法。

其他回答

这是一个公平的问题,他除了明显的……

缺点包括:

性能影响 查询优化器使用字段大小来确定最有效的执行计划

“1。数据库扩展和页面的空间分配是灵活的。因此,当使用update向字段添加信息时,如果新数据比之前插入的数据长,数据库就必须创建一个指针。这样,数据库文件将变得碎片化=从索引到删除、更新和插入,几乎所有方面的性能都较低。” http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx

集成影响——其他系统很难知道如何与您的数据库集成 不可预测的数据增长 可能的安全问题,例如占用所有磁盘空间可能导致系统崩溃

这里有一篇好文章: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html

一个不使用max或文本字段的原因是,你不能执行在线索引重建,即REBUILD WITH online = ON,即使与SQL Server企业版。

当你知道字段将在一个固定的范围内时,这不是一个好主意——例如5到10个字符。我想我只会在不确定长度的情况下使用max。例如,电话号码永远不会超过一定数量的字符。

你能诚实地说,你不确定表中每个字段的大约长度要求吗?

我确实明白你的意思——有些字段我肯定会考虑使用varchar(max)。

有趣的是,MSDN文档总结得很好:

的大小时使用varchar 列数据条目变化很大。 的大小时使用varchar(max) 列数据条目变化很大, 大小可能超过8000字节。

关于这个问题有一个有趣的讨论。

一个问题是,如果你必须使用多个版本的SQL Server, MAX并不总是有效的。因此,如果您正在使用遗留DB或涉及多个版本的任何其他情况,您最好非常小心。

把它当做另一个安全等级。您可以设计没有外键关系的表(完全有效),并确保完全在业务层上存在关联实体。然而,外键被认为是很好的设计实践,因为它们增加了另一个约束级别,以防业务层出现问题。同样,字段大小限制和不使用varchar MAX。