在SQL Server 2005中,使所有字符字段nvarchar(MAX)而不是明确指定长度是否有任何缺点,例如nvarchar(255)?(除了显而易见的一个,你无法限制数据库级别的字段长度)
在MSDN论坛上询问了同样的问题:
Varchar(max)vs Varchar(255)
从原始帖子(更多信息):
将数据存储到VARCHAR(N)列时,值以相同的方式物理存储.但是当您将其存储到VARCHAR(MAX)列时,屏幕后面的数据将作为TEXT值处理.因此在处理VARCHAR(MAX)值时需要一些额外的处理.(仅当尺寸超过8000时)
VARCHAR(MAX)或NVARCHAR(MAX)被视为"大值类型".大值类型通常存储在"行外".这意味着数据行将有一个指向存储"大值"的另一个位置的指针...
这是一个公平的问题,除了明显的......
缺点可能包括:
性能影响查询优化器使用字段大小来确定最有效的exectution计划
"1.数据库的扩展和页面中的空间分配是灵活的.因此,当使用更新向字段添加信息时,如果新数据比先前插入的数据长,则数据库必须创建指针.这个数据库文件将变得支离破碎=从索引到删除,更新和插入几乎所有内容都会降低性能." 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
有时您希望数据类型对其中的数据强制执行某些意义.
比如说你有一个真的不应该长于20个字符的列.如果您将该列定义为VARCHAR(MAX),则某些恶意应用程序可能会在其中插入一个长字符串,您将永远不知道,或者有任何方法可以阻止它.
下次您的应用程序使用该字符串时,假设字符串的长度对于它所代表的域来说是适度且合理的,您将会遇到不可预测且令人困惑的结果.
根据接受的答案中提供的链接,似乎:
存储在nvarchar(MAX)
字段中的100个字符将在字段中存储与100个字符不同nvarchar(100)
- 数据将以内联方式存储,您不会有"读取和写入数据"的开销.所以不用担心.
如果大小大于4000,数据将自动存储在"行外",这就是您想要的.所以也不用担心.
然而...
您无法在nvarchar(MAX)
列上创建索引.您可以使用全文索引,但无法在列上创建索引以提高查询性能.对我来说,这封印了这笔交易......总是使用nvarchar(MAX)是一个明显的缺点.
结论:
如果你想在整个数据库中使用一种"通用字符串长度",它可以被编入索引并且不会浪费空间和访问时间,那么你可以使用nvarchar(4000)
.
我检查了一些文章并从中找到了有用的测试脚本:http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx 然后将其更改为NVARCHAR(10)与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
把它想象成另一个安全级别.您可以设计没有外键关系的表 - 完全有效 - 并确保完全在业务层上存在关联实体.但是,外键被认为是很好的设计实践,因为它们会增加另一个约束级别,以防万一在业务层上出现问题.字段大小限制也是如此,不使用varchar MAX.
不使用max或text字段的原因是你无法执行在线索引重建,即使用SQL Server企业版,REBUILD WITH ONLINE = ON.