SQL Server 2005:数据类型最大值

来源:互联网 发布:手机商城模板源码 编辑:程序博客网 时间:2024/05/09 03:43
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和VARBINARY变量在达到8000个字节的极限的时候可以自动“升级”到MAX版本。例如,如下的批处理:

  DECLARE @String1 VARCHAR(4001)

  DECLARE @String2 VARCHAR(4001)

  SET @String1 = REPLICATE('1', 4001)

  SET @String2 = REPLICATE('2', 4001)

  SELECT LEN(@String1 + @String2)

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

  DECLARE @String1 VARCHAR(4001)

  DECLARE @String2 VARCHAR(4001)

  SET @String1 = REPLICATE('1', 4001)

  SET @String2 = REPLICATE('2', 4001)

  SELECT LEN(CONVERT(VARCHAR(MAX), @String1) + @String2)

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

  SELECT LEN(REPLICATE('1', 8002))

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

  SELECT LEN(REPLICATE(CONVERT(VARCHAR(MAX), '1'), 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('1', 8000))

  But the following row will result in an overflow:

  INSERT BigStrings (BigString)

  VALUES (REPLICATE(CONVERT(VARCHAR(MAX), '1'), 100000))

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

  EXEC sp_tableoption

  'BigStrings',

  'large value types out of row',

  '1'

  看看定义一个MAX数据类型有多容易,与他们提供的灵活性一样,一些数据设计师将会被引诱以下列的方式开始定义表:

  CREATE TABLE Addresses

  (

  Name VARCHAR(MAX),

  AddressLine1 VARCHAR(MAX),

  AddressLine2 VARCHAR(MAX),

  City VARCHAR(MAX),

  State VARCHAR(MAX),

  PostalCode VARCHAR(MAX)

  )

  设计师要注意了:不要这样做!一个企业中的数据模型既应该包含有具有实际限制的数据,还要给用户接口设计师有关字段尺寸的大致的指导。像这样的表又该创建什么样的用户接口呢?

  除了数据整合和用户接口含义之外,如果设计师这样不必要地使用这些类型还会带来性能上的损害。记住,查询优化器使用字段的尺寸作为判断优化查询计划的众多标准之一。对于这个表,优化器几乎没有任何选择。