是否有任何缺点总是使用为nvarchar(MAX)?是否有任何缺点总是使用为nvarchar(MAX

2019-05-05 15:29发布

在SQL Server 2005中,有没有什么缺点使所有字符字段为nvarchar(MAX),而不是一个指定的长度明确,如为nvarchar(255)? (除了明显的一个,你是不是能够限制在数据库级字段长度)

Answer 1:

同样的问题,有人问MSDN论坛:

  • VARCHAR(最大值)与VARCHAR(255)

从原来的职位(更多的信息有):

当存储数据到VARCHAR(N)列中,值被物理地存储在相同的方式。 但是,当你把它存储到VARCHAR(MAX)列,屏幕后面的数据作为一个文本值进行处理。 因此,有一个VARCHAR(MAX)值打交道时需要一些额外的处理。 (仅当尺寸超过8000)

VARCHAR(MAX)或nvarchar(MAX)被认为是一个 '大的值类型'。 大值类型通常存储“出行的”。 这意味着数据行将有一个指针,它指向“大值”存储在另一位置...



Answer 2:

这是一个公平的问题,他从没有明显分开的状态...

缺点可能包括:

性能影响查询优化器使用字段的大小来确定最efficent exectution计划

“1.在空间alloction扩展和数据库的页面是灵活的。因此,使用更新的字段中添加信息时,你的数据库将不得不如果新的数据比以前的插入,这将数据库文件更长的时间来建立一个指针会变得支离破碎=低性能的几乎一切,从指数中删除,更新和插入。“ 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



Answer 3:

有时候你想要的数据类型来实施对其中的数据有所了解。

例如说,你有真的不应该超过,比如说,20个字符的列。 如果定义列VARCHAR(MAX),一些恶意应用程序可以插入一个长字符串到它,你永远不会知道,或者具有防止它的任何方式。

应用程序使用的字符串,假定字符串的长度是适度的,合理的为它代表域下的下一次,你将体验到一个不可预知的和令人困惑的结果。



Answer 4:

总部设在接受的答案提供的链接似乎:

  1. 存储在100个字符nvarchar(MAX)字段将存储无异于100个字符的nvarchar(100)场-该数据将被存储在线,你会不会有阅读的开销和写入数据“出列”。 所以不必担心在那里。

  2. 如果大小大于4000的数据将被存储“排出来的”自动,这是你想要的东西。 所以不必担心有任何。

然而...

  1. 不能创建上的一个指数nvarchar(MAX)列。 您可以使用全文索引,但不能创建在列的索引来提高查询性能。 对我来说,这个密封处理......这是一个明确的缺点总是使用为nvarchar(MAX)。

结论:

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



Answer 5:

我查了一些文章,从这个发现有用的测试脚本: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx然后改变它NVARCHAR(10)VS NVARCHAR(4000)与NVARCHAR(MAX之间的比较),并使用指定的电话号码,但使用MAX时,当我不觉得速度差。 你可以自己测试一下。 希望这有助于。

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
        @StartTime DATETIME;
--=====         
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO


Answer 6:

可以把它看成只是一个安全水平。 你可以设计你的表没有外键关系 - 完全有效的 - 并确保整个业务层上的相关实体的存在。 但是,外键被视为良好的设计做法,因为他们增加的情况下,一些在业务层上打乱了另一个约束水平。 这同样适用于场大小的限制,而不是使用VARCHAR MAX。



Answer 7:

理由不使用max或文本字段的是,你不能执行联机索引重建即与SQL Server企业版在线=上重建平衡。



Answer 8:

我发现的唯一的问题是,我们发展我们的SQL Server 2005上的应用程序,并且在一个情况下,我们要支持SQL Server 2000中我了解到, 硬的方式 ,SQL Server 2000不喜欢VARCHAR或MAX选为nvarchar。



Answer 9:

当你知道的领域将是一组不错的主意范围 - 5到例如10个字符。 我想我只能用最大如果我不知道的长度将是什么。 例如,一个电话号码绝不会超过一定数目的字符进行比较。

你可以诚实地说,你不确定你的表格,每场的大致长度要求是什么?

我明白你的意思though-还有一些领域我肯定会考虑使用VARCHAR(最大值)。

有趣的是, MSDN文档概括起来相当不错:

使用VARCHAR,当列数据项的大小差异相当大。 使用VARCHAR(最大值)时列数据项的大小差异相当大,而且规模可能超过8000个字节。

有在这里的问题一个有趣的讨论 。



Answer 10:

数据库的工作是存储数据,以便它可以由企业使用。 使得数据有用的部分是确保它是有意义的。 允许某人输入的字符,数量没有限制他们的名字并不保证有意义的数据。

建立这些约束到业务层是一个好主意,但是,这并不保证数据库将保持不变。 以保证数据的规则不被侵犯的唯一方法是在数据库中的最低级可以强制他们。



Answer 11:

一个问题是,如果您有多个SQL Server版本的工作,MAX将不总是工作。 所以,如果你是与传统数据库的或涉及多个版本的任何其他情况下工作,你最好要非常小心。



Answer 12:

正如上面指出,它主要是存储和性能之间的折衷。 至少在大多数情况下。

然而,有应该在N / VARCHAR(N)选择N / VARCHAR(最大值)时,可以考虑至少一种其他因子。 将会对数据进行索引(例如,比方说,一个姓)? 由于MAX定义被认为是一个LOB,则定义为MAX任何不适用于索引。 并没有索引,涉及WHERE子句中的数据作谓语的任何查询将被强制进入全表扫描,这是你可以得到的数据查找的最差表现。



Answer 13:

1)在SQL Server将与为nvarchar(最大交易)VS为nvarchar(正时更多地利用资源(分配的内存和CPU时间)),其中n是特定领域的一些。

2)这是什么意思在问候的表现?

在SQL Server 2005中,我查询13000行的数据从表15为nvarchar(最大)列。 我反复计时的查询,然后更改的列到nvarchar的(255)或更小。

优化前的查询均在2.0858秒。 变更后的查询中平均1.90秒返回。 这是大约184毫秒的改进,基本选择*查询。 这是一个8.8%的改善。

3)我的结果是与表明有一个性能差异的几个其他文章同意。 根据您的数据库和查询的,改善的比例可以有所不同。 如果你没有大量的并发用户还是非常多条记录,那么性能差异将不会对你的问题。 然而,性能差异会随着更多的记录和并发用户增加。



Answer 14:

我有这填补串并把输出为varchar(最大)一个UDF。 如果这是用来铸造回的列适当的大小进行调整,而不是直接,表现得非常差。 最后我把UDF来一个任意长度的一个大注,而不是依靠UDF的所有呼叫者字符串重新转换为更小的尺寸。



Answer 15:

有趣的链接: 为什么要使用一个VARCHAR时,您可以使用文字?

这是关于PostgreSQL和MySQL,因此性能分析是不同的,但对于“显性”的逻辑仍然成立:为什么强迫自己总是担心一些与自己相关的时间一小部分? 如果您保存的电子邮件地址的变量,你会使用“字符串”不是“字符串限制为80个字符”。



Answer 16:

遗留系统的支持。 如果你有一个使用该数据的系统,并预计将一定长度,然后在数据库强制执行长的好地方。 这是不理想,但遗留系统有时并不理想。 = P



Answer 17:

如果所有的行(所有列)中的数据绝不会合理地提出8000个或更少的字符,然后在数据层的设计应加强这一点。

数据库引擎是更有效藏在心里了Blob存储的。 较小的可以限制一个排好。 更行,你可以在一个页面补习班就更好了。 该数据库只是进行更好的时候,有权访问较少的页面。



Answer 18:

我的测试表明,有选择的时候差别。

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;


Answer 19:

主要缺点我能看到的是,让我们说你有这样的:

哪一个为您提供有关所需UI数据的信息最多?

这个

            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]


Answer 20:

一个缺点是,你将围绕一个不可预知的变量来设计,你可能会忽略,而不是采取内部SQL Server数据结构的优势,逐步由行(S),页数,以及程度(S)。

这让我想起数据结构排列在C,并意识到的对齐通常被认为是一件好事(TM)。 类似的想法,不同的上下文。

为MSDN页页和扩展

为MSDN页面行溢出数据



Answer 21:

这将导致性能问题,虽然可能不会引起任何实际问题,如果你的数据库是小。 每个记录会占用更多的空间,在硬盘驱动器和数据库需要读取磁盘的更多的部门,如果你经历了很多的记录在一次搜索。 例如,一个小型的唱片可以容纳50到部门和大型记录可以容纳5你需要使用大的记录磁盘读取10倍的数据。



Answer 22:

这将使屏幕的设计更难,因为你将不再能够预测你的控制应该有多宽是。



文章来源: Are there any disadvantages to always using nvarchar(MAX)?