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


当前回答

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

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

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

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

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

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

其他回答

我能看到的主要缺点是,假设你有这样的情况:

哪一个提供了关于UI所需数据的最多信息?

This

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

还是这个?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

同样的问题也出现在MSDN论坛上:

Varchar(max) vs Varchar(255)

原文(更多信息):

When you store data to a VARCHAR(N) column, the values are physically stored in the same way. But when you store it to a VARCHAR(MAX) column, behind the screen the data is handled as a TEXT value. So there is some additional processing needed when dealing with a VARCHAR(MAX) value. (only if the size exceeds 8000) VARCHAR(MAX) or NVARCHAR(MAX) is considered as a 'large value type'. Large value types are usually stored 'out of row'. It means that the data row will have a pointer to another location where the 'large value' is stored...

我有一个udf填充字符串,并把输出varchar(max)。如果直接使用它,而不是将其转换回正在调整的列的适当大小,则性能非常差。我最终将udf设置为一个任意长度的大音符,而不是依赖udf的所有调用者将字符串重新转换为较小的大小。

这将导致性能问题,尽管如果数据库较小,可能永远不会导致任何实际问题。每条记录将占用硬盘驱动器上更多的空间,如果您一次搜索大量记录,数据库将需要读取更多的磁盘扇区。例如,一个小的记录可以适合50个扇区,而一个大的记录可以适合5个扇区。如果使用大记录,则需要从磁盘读取10倍的数据。

根据已接受的答案中提供的链接,似乎是:

存储在nvarchar(MAX)字段中的100个字符将与存储在nvarchar(100)字段中的100个字符没有区别-数据将内联存储,并且您不会有“行外”读取和写入数据的开销。所以不用担心。 如果大小大于4000,数据将自动“行外”存储,这是你想要的。所以也不用担心。

然而……

不能在nvarchar(MAX)列上创建索引。可以使用全文索引,但不能在列上创建索引以提高查询性能。对我来说,这就决定了……总是使用nvarchar(MAX)是一个明显的缺点。

结论:

如果你想要一种贯穿整个数据库的“通用字符串长度”,它可以被索引,并且不会浪费空间和访问时间,那么你可以使用nvarchar(4000)。