奇宝库 > SQL Server 2005:数据类型最大值

SQL Server 2005:数据类型最大值

开始很简单。MegaWare的市场部门想要一个新的网站来发布文档,开发团队觉得使用sql server 2000数据库作为文档存储仓库会让事情变得更简单。Steve MegaWare是数据库管理员,他没有看到任何大问题。将文档存储在数据库中而不是使用文件系统意味着服务器需要做更多的工作,但这也使备份和管理更加容易。与数据库文件系统不同步也应该是不可能的。

市场上希望存储的许多文档都超过了8000字节,因此很明显,VARCHAR不是适合这项工作的数据类型。相反,文本数据类型用于定义存储数据的字段。因为每个文本可以容纳2GB的内容,所以文本存储市场部同事扔进数据库的最大文件是没有问题的。

几个月过去了,市场用大量无聊的拷贝填满了整个数据库。但这不是史蒂夫真正关心的。数据库愉快地嗡嗡作响,每个人都对项目的结果感到满意。

直到公司口号改变的大日子。营销团队认为“MegaWare:真的很酷!”比原来的“这是MegaWare的方式或高速公路!”听起来好多了。因为营销团队已经在仓库中的每个文档的页脚中嵌入了原始标语,所以现在Steve的工作是更改所有这些文档的页脚。

“没问题,”史蒂夫想。他打开了SQL Server查询分析器工具,并执行了以下T-SQL批处理:

更新营销文档

设置文档=

替换(文档,

这是MegaWare的方式或高速公路!

超级软件:真的很酷!)

当他看到错误信息时,史蒂夫轻松的笑容很快消失了。替换函数的参数1,文本数据类型无效。

编写替换函数时,它对文本数据类型没有影响。它也不适用于CHARINDEX或SUBSTRING ——,或者至少它们不支持超过8000个字符。此外,开发人员忘记了处理文本或图像类型的局部变量;实际上不支持任何操作。即使只是简单地更新文档中的子字符串,也需要一些晦涩的东西和函数,比如READTEXT和WRITETEXT,它们很难使用。这并不是说开发人员或忙碌的数据库管理员花费时间使用不同类型的函数,因为他们想弄清楚如何正确地使用它们。

SQL Server开发人员非常幸运,他们将摆脱乌云,看到蓝天。Sql server 2005引入了一系列名为MAX的新数据类型。这是VARCHAR、NVARCHAR和VARBINARY类型的扩展,这些类型以前被限制在8000字节以下。MAX最多可以容纳2GB的数据,和文本、图像一样是——,完全兼容所有SQL Server内置的字符串函数。

用MAX关键字定义某种MAX类型的变量就像替换字符串的大小(对于VARCHAR/NVARCHAR)或字节(对于VARBINARY)一样简单。

声明@BigString VARCHAR(MAX)

SET @BigString='abc '

虽然这个变量可以自由操作,并可以传递给任何内置的字符串函数,但兼容性并不是没有问题。首先,开发者不能指望指定大小的VARCHAR和VARBINARY变量在达到8000字节的限制时会自动“升级”到MAX版本。例如,下面的批处理:

声明@String1 VARCHAR(4001)

声明@String2 VARCHAR(4001)

SET @String1=REPLICATE('1 '4001)

SET @String2=REPLICATE('2 '4001)

选择LEN(@String1 @String2)

4001 4001=8002,但是指定大小的VARCHAR的限制是8000。因为这两个变量都不是MAX类型,所以LEN函数的结果是8000,而不是8002。当连接两个变量时,一个简单的修正方法是将这两个变量中的一个声明为VARCHAR(MAX)或者转换其中一个。当与指定大小的类型连接时,首选MAX类型,最终结果是MAX类型。所以,下面一批的结果是8002,正如我们所料:

声明@String1 VARCHAR(4001)

声明@String2 VARCHAR(4001)

SET @String1=REPLICATE('1 '4001)

SET @String2=REPLICATE('2 '4001)

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

当传递给字符串函数时,开发人员认识到字符串的原始含义是默认指定的,而不是MAX类型,这一点也很重要。例如,以下查询的结果令人惊讶:

选择镜头(复制(' 1 '8002))

因为字符串“1”被视为指定大小的VARCHAR,而不是VARCHAR(MAX),所以结果是80003354。但是,在SQL Server 2005中,REPLICATE函数可以生成高达2GB的字符串。要解决这个问题,您可以将字符串转换为VARCHAR(MAX ),这样函数将输出相同的类型:

SELECT LEN(REPLICATE(CONVERT(VARCHAR(MAX),' 1 '),8002))

这个查询现在将返回预期的结果:8002。记住,总是非常仔细地测试用新特性编写的代码;隐藏的问题,比如上面描述的那些,在最坏的时候可能并且无疑会带来灾难性的后果。

除了变量,MAX类型也可用于定义表的字段:

创建表大字符串

BigString VARCHAR(最大)

)

在表中使用时,认识到MAX类型的行溢出行为与TEXT和IMAGE类型略有不同是非常重要的。在SQL Server中,最大行大小为8060字节。要超过这一限制,并且仍然管理每种类型高达2GB的存储,存储引擎将自动中断存储在文本和图像类型中的数据,在行中只留下一个16字节的指针。这意味着行大小减小了,这对性能有好处。但是,检索大数据的成本很高,因为它不是与同一行中的数据存储在同一个位置。

默认情况下,MAX数据类型混合使用TEXT/IMAGE溢出行为和正常大小的VARCHAR/VARBINARY类型的行为。如果一个字段中的数据总量加上表中所有其他字段的数据总量小于8060字节,则数据将存储在行中。如果数据超过8060字节,MAX字段中的数据将存储在该行之外。对于具有大字符串的表,以下行将与表中的其他数据存储在同一数据页中:

插入大字符串(BigString)

值(复制(' 1 '8000))

但是下面的行将导致溢出:

插入大字符串(BigString)

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

您可以在每个表的基础上更改MAX数据类型的默认行为,它们的行为类似于文本和图像类型。这是通过使用sp_tableoption存储过程中的“行外大数值类型”选项来实现的。为了修改大字符串表,以便以与文本和图像数据类型相同的方式处理MAX类型,可以使用以下T-SQL:

执行sp_tableoption

大字符串'

行外的大值类型,

'1'

看看定义MAX数据类型有多简单。就像它们提供的灵活性一样,一些数据设计人员可能会尝试以下列方式定义表:

创建表格地址

名称VARCHAR(MAX),

AddressLine1 VARCHAR(MAX),

AddressLine2 VARCHAR(MAX),

城市VARCHAR(最大值),

状态变量字符(最大值),

PostalCode VARCHAR(最大值)

)

设计师们注意了:不要这样!企业中的数据模型不仅应该包含具有实际限制的数据,还应该为用户界面设计者提供关于字段大小的一般说明。像这样的表格应该创建什么样的用户界面?

除了数据集成和用户界面的意义之外,如果设计人员不必要地使用这些类型,将会带来性能损害。请记住,查询优化器使用字段的大小作为判断优化的查询计划的许多标准之一。对于这个表,优化器几乎没有选择。

现在,您知道MAX数据类型为SQL Server 2005在处理大数据方面增加了极大的灵活性。但是,MegaWare中那个不幸的数据库管理员史蒂夫会怎么样呢?仍然坚持使用sql server 2000,他开始更新他的简历,想象着如果他不更新他的表格,他的工作就会失去。但他也是幸运的,——和全世界MegaWare产品的支持者,——。你可以通过谷歌搜索快速找到这篇文章《在TEXT字段中查找并替代》,这篇文章告诉他如何正确更新。他花了一整夜研究材料;几个月后,文本和图像数据类型将只是一种不愉快的记忆。

本文来自网络,不代表本站立场,转载请注明出处: