在Microsoft SQLServer2005及以上的版本中,对于varchar(n)、nvarchar(n)和varbinary(n)有了max的扩展。可以使用如:varchar(max)、nvarchar(max)和varbinary(max)的大值数据类型来存储最多2^30-1个字节的数据。
这几个数据类型在行为上和较小的数据类型 varchar、nvarchar 和 varbinary 相同。

微软的说法是用这个数据类型来代替之前的text、ntext 和 image 数据类型,它们之间的对应关系为:
varchar(max)-------text;
nvarchar(max)-----ntext;
varbinary(max)----image.

有了大值数据类型之后,在对大值数据操作的时候要比以前灵活的多了。比如:之前text是不能用‘like’的,有了varchar(max)之后就没有这些问题了,因为varchar(max)在行为上和varchar(n)上相同,所以,可以用在varchar的都可以用在varchar(max)上。
以varchar为例,varchar支持8000字符,Text支持2GB字符,但是,替换函数在编写出来的时候,就对TEXT数据类型不起作用。

Update TableName Set DocuMent=REPLACE(DocuMent,String1,String2) /*此行将报错*/

同样也对CHARINDEX或者SUBSTRING不起作用——或者至少是他们在超过8千个字符的情况下不起作用。更进一步地讲,如果开发人员忘了处理TEXT或者IMAGE类型的本地变量,则实际上不支持任何操作。即使是简单地更新一个文档中的一个子字符串都需要用到很多的东西,以及难以使用的类似READTEXT和WRITETEXT的函数。

SQL Server 2005引入了一系列新的被称为max的数据类型(或者说是参数类型)。这是varchar、nvarchar 和 varbinary类型的扩展,这几种类型以前被限制在8000字节以下。max可以容纳高达2GB的数据,与TEXT和IMAGE一样——并且完全兼容所有的SQL Server内置的字符串函数。
用max关键字定义一个某种max类型的变量与替代字符串的尺寸(为varchar、nvarchar的时候)或者字节(为varbinary的时候)一样简单。

DECLARE @BigString varchar(max)
SET @BigString = 'abc'

虽然这个变量可以自由地操纵,并且可以传递给任何的内置的字符串函数,兼容性仍然不是没有问题。首先,开发人员不能期望指定了尺寸的varchar和nvarchar变量在达到8000个字节的极限的时候可以自动“升级”到max版本。例如,如下的批处理:

DECLARE @String1 varchar(4001)
DECLARE @String2 varchar(4001)
SET @String1 = REPLICATE('', 4001)
SET @String2 = REPLICATE('', 4001)
SELECT LEN(@String1 + @String2)

4001+4001=8002,但是指定了尺寸的varchar(n)的极限是8000。因为这两个变量中没有一个是max类型,LEN函数的结果就是8000,不是8002。在将两个变量连接的时候,一种简单的修正方法就是声明这两个变量中的一个为varchar(max)或者将其中的一个变量进行转换。与一个规定了尺寸的类型进行连接的时候,优先考虑max类型,最终结果是max类型。所以,以下批处理的结果是8002,正如我们期望的一样:

DECLARE @String1 varchar(4001)
DECLARE @String2 varchar(4001)
SET @String1 = REPLICATE('', 4001)
SET @String2 = REPLICATE('', 4001)
SELECT LEN(CONVERT(varchar(max), @String1) + @String2)

在传递给字符串函数的时候,开发人员意识到字符串的原意在默认情况下是规定了尺寸的,而不是max类型,也是至关重要的。例如,以下查询的结果就很令人惊奇:

SELECT LEN(REPLICATE('', 8002))

因为字符串‘1’是被作为规定了尺寸的varchar对待,而不是varchar(max),结果就是8000——但是在SQL Server 2005中,REPLICATE函数能够产生高达2GB的字符串。要修正这个问题,可以将字符串转换为varchar(max),这样函数就会输出同样的类型了:

SELECT LEN(REPLICATE(CONVERT(varchar(max), ''), 8002))

这个查询现在将会返回期望的结果:8002。记住,总是要对采用了新特性编写的代码进行非常仔细的测试。隐藏的问题,例如上面描述的问题,可能并且毫无疑问地会在最坏的时间里造成灾难性的后果。

除了变量之外,max类型也可以用于定义表的字段:

CREATE TABLE BigStrings (BigString varchar(max))

当用于表的时候,意识到max类型具有与TEXT和IMAGE类型稍微不同的行溢出行为是非常重要的。在SQL Server中,最大的行尺寸是8060字节。要超过这个限制,并且仍然管理每个都拥有高达2GB的存储,用TEXT和IMAGE类型存储的数据会被存储引擎自动地断行,在行里只留下一个16字节的指针。这意味着行的尺寸是减少了,这对性能有好处。然而,检索大数据是昂贵的,因为它不是与同一行的数据存放在同一个位置。

max数据类型在默认情况下,使用TEXT/IMAGE溢出行为和正常尺寸的varchar/varbinary类型的行为的混合方式。如果一个字段的数据,加上表中所有其他字段的数据,总量少于8060字节,数据就存放在行内。如果数据超过8060字节,max字段的数据就会存放在行外。对于大字符串的表,以下的行将会与表中的其他数据存储在同一个数据页内:

INSERT BigStrings (BigString) VALUES (REPLICATE('', 8000))
--But the following row will result in an overflow:
INSERT BigStrings (BigString) VALUES (REPLICATE(CONVERT(varchar(max), ''), 100000))

你可以更改max数据类型在每个表的基础上的默认的行为,它们会表现得和TEXT和IMAGE类型一样。这是通过使用sp_tableoption 存储过程中的“大数值类型在行外”选项实现的。为了修改大字符串表以将max类型的处理方式变得与TEXT和IMAGE数据类型的处理方式相同,可以使用如下的T-SQL:

EXEC sp_tableoption
  'BigStrings',  
  'large value types out of row',
  ''

扩展:
既然是以max有这么多灵活性,一些数据库设计师将会被引诱以下列的方式开始定义表:

CREATE TABLE Addresses(
  Name varchar(max),
  AddressLine1 varchar(max),
  AddressLine2 varchar(max),
  City varchar(max),
  State varchar(max),
  PostalCode varchar(max)
  )

我建议你最好不要这样做,一个企业应用中的数据模型既应该包含有具有实际限制的字段,还要给程序设计师提供有关字段尺寸的指导文档。像这样的表又该创建什么样的文档呢?
总知,max标记的数据类型为SQL Server 2005及之后版本处理大数据增加了很大部分的灵活性,但在使用中需要自己根据需求选择字段类型。

原文链接

SQL Server中VARCHAR(MAX)和NVARCHAR(MAX)使用时要注意的问题(转载)的更多相关文章

  1. SQL Server中数据库文件的存放方式,文件和文件组 (转载)

    简介 在SQL SERVER中,数据库在硬盘上的存储方式和普通文件在Windows中的存储方式没有什么不同,仅仅是几个文件而已.SQL SERVER通过管理逻辑上的文件组的方式来管理文件.理解文件和文 ...

  2. SQL Server 中VARCHAR(MAX)变量赋值引起的性能问题。

    案例环境: 操作系统版本 : Windows Server 2008 R2 Standard  SP1 数据库版本   :  Microsoft SQL Server 2012 (SP1) - 11. ...

  3. SQL Server中,varchar和nvarchar如何选择

    正常情况下,我们使用varchar也可以存储中文字符,但是如果遇到操作系统是英文操作系统并且对中文字体的支持不全面时, 在SQL Server存储中文字符为varchar就会出现乱码(显示为??). ...

  4. SQL Server中varchar和nvarchar的区别

    varchar(n) 长度为 n 个字节的可变长度且非 Unicode 的字符数据.n 必须是一个介于 1 和 8,000 之间的数值.存储大小为输入数据的字节的实际长度,而不是 n 个字节.nvar ...

  5. SQL Server 中怎么查看一个字母的ascii编码或者Unicode编码(转载)

    在sql中怎么查看一个字符的ascii编码或Unicode编码: SELECT ASCII('a') AS [AsciiNum]--字符获取ASCII码 SELECT UNICODE(N'a') AS ...

  6. SQL Server中的“最大并行度”的配置建议

    SQL Server中的最大并行度(max degree of parallelism)如何设置呢? 设置max degree of parallelism有什么好的建议和指导方针呢?在微软官方文档R ...

  7. SQL Server中Text和varchar(max)数据类型区别

    SQL Server中Text和varchar(max)数据类型区别   以前只知道text和image是可能被SQL Server淘汰的数据类型,但具体原因不太清楚,今天读书的时候发现了text与v ...

  8. SQL Server中Text和varchar(max) 区别

    SQL Server 2005之后版本:请使用 varchar(max).nvarchar(max) 和 varbinary(max) 数据类型,而不要使用 text.ntext 和 image 数据 ...

  9. Sql server中的 nvarchar(max) 到底有多大?(转载)

    问题: SQL server中的nvarchar(max)最大的长度是4000个字吗? 如果字段的内容超过4000个字时用什么类型呢?text 还是binary?他们的最大长度是多少?比如字段放的是长 ...

随机推荐

  1. 关于如何修改一张表中所有行与选定字段的同sql多行语句的添加方法

    利用Excel以及word文档进行操作 将表的字段以及数据全部放入Excel表中并保存. 在word表中将写好的sql语句放入文档,利用邮件--选择收件人--使用现有列表--(选择之前做好的Excel ...

  2. Redis开启远程访问及密码

    一.开启远程访问 1.开放端口 firewall-cmd --zone=public --add-port=6379 firewall-cmd --zone=public --add-port=637 ...

  3. 前端性能优化 http请求的过程及潜在的优化点

    CS架构:比如我们的代码开发好,打包成apk,发布到平台,那么最终怎么运行到用户的手机上呢,用户首先需要从相关的应用商城下载这个apk包,并且运行这个 apk 包,那么这个 apk 包就会被解压,最后 ...

  4. CodeForces 150E: Freezing with Style

    题目传送门:CF150E. 据说这个傻逼题还有一个 \(\log\) 的做法,但是我还不会. 题意简述: 给定一棵 \(n\)(\(2\le n\le 10^5\))个点的树,边有边权. 定义一条路径 ...

  5. Nginx下HTML页面POST请求静态JSON数据返回405状态

    在浏览器访问HTML页面,发现一些静态JSON数据没有显示,F12查看,如下图所示: 可以看到请求方式为POST 将请求链接复制在浏览器地址栏访问,可以正常请求到数据 F12查看,可以看到请求方式为G ...

  6. python字符串使用方法归纳

    字符串的意思就是“一串字符”,比如“Hello,Charlie”是一个字符串,“How are you?”也是一个字符串. Python 要求字符串必须使用引号括起来,使用单引号也行,使用双引号也行, ...

  7. 让Discuz! X3.2 SEO标题里的“-”支持空格

    打开Discuz!根目录下source\class\helper\helper_seo.php文件找到如下代码: public static function strreplace_strip_spl ...

  8. Python基础之内置方法

    目录 字符串的内置方法 按索引取值 切片(顾头不顾尾,步长) 长度len 成员运算 移除两边空白strip 切分split 循环 lower&upper startswith & en ...

  9. Angle Beats Gym - 102361A(计算几何)

    Angle Beats \[ Time Limit: 4000 ms \quad Memory Limit: 1048576 kB \] 题意 给出 \(n\) 个初始点以及 \(q\) 次询问,每次 ...

  10. three.js 加载STL文件

    注意: TrackballControls.js 和 TDSLoader.js 都引用了 three.module.js,特别注意引用的路径 比如: 直接代码咯 <!DOCTYPE html&g ...