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


当前回答

数据库的任务是存储数据,以供企业使用。让数据有用的一部分是确保它是有意义的。允许用户为自己的名字输入无限个字符并不能确保数据有意义。

将这些约束构建到业务层是一个好主意,但这并不能确保数据库保持完整。保证数据规则不被违反的唯一方法是在数据库中尽可能低的级别执行它们。

其他回答

如果一行中的所有数据(对于所有列)不会合理地占用8000或更少的字符,那么数据层的设计应该强制执行这一点。

数据库引擎可以更有效地将所有内容排除在blob存储之外。限制行越小越好。一页中可以塞进的行越多越好。当数据库必须访问更少的页面时,它的性能会更好。

我检查了一些文章,并从http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx找到了有用的测试脚本 然后将其更改为NVARCHAR(10) vs NVARCHAR(4000) vs 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

有时您希望数据类型对其中的数据强制执行一些意义。

例如,你有一列不应该超过20个字符。如果您将该列定义为VARCHAR(MAX),一些恶意应用程序可能会向其中插入一个长字符串,而您永远不会知道,或者没有任何方法来阻止它。

下次应用程序使用该字符串时,假设字符串的长度对于它所代表的领域来说是适度和合理的,那么您将体验到一个不可预测和令人困惑的结果。

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

缺点包括:

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

“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

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