Christian4145 Asked: 2017-09-27 02:10:43 +0800 CST2017-09-27 02:10:43 +0800 CST 2017-09-27 02:10:43 +0800 CST SQL Server 中的 LOB 和二进制数据有什么区别? 772 谈到“LOB”和“二进制”数据时有什么区别? 就存储在单独文件组中的二进制数据而言,是否相同,还是有区别? sql-server 1 个回答 Voted Best Answer sepupic 2017-09-27T03:28:06+08:002017-09-27T03:28:06+08:00 根据Technet:数据类型 (Transact-SQL) 在 SQL Server 中,根据它们的存储特性,某些数据类型被指定为属于以下组: 大值数据类型:varchar(max)、nvarchar(max) 和 varbinary(max) 大型对象数据类型:text、ntext、image、varchar(max)、nvarchar(max)、varbinary(max) 和 xml 所以这些类型被定义为LOB 数据类型。当您询问时,binary data我想您是在谈论binary数据类型的数据。 Binary数据类型可以是以下两种之一:固定长度和可变长度。 具有最大字符数而不是 MAX 说明符的固定长度二进制数据类型或可变长度 varbinary 数据类型在第一种情况下始终存储在行中,在第二种情况下(可能)存储在行外,并且不是 LOB 数据类型。 另一方面,根据此分类(来自同一篇 Technet 文章): varchar(max), nvarchar(max), text,ntext数据类型是CHARACTER字符串而不是 BINARY字符串。 所以 LOB 数据类型包括不是二进制字符串的 CHARACTER 字符串。 结论 二进制数据 <> LOB 数据 唯一相同的情况是您的数据定义为 VARBINARY(MAX) 回到关于如何存储 LOB 数据的评论中的问题。 如果该值是旧的遗留类型之一(text, ntext, image),则默认情况下将其存储在行外。 Off-row 表示数据记录中有一个指针指向存储实际 LOB 值的记录的位置或存储 LOB 值的树的开始: 此图像来自Dmitri Korotkevitch 的 Pro SQL Server Internals 第一版一书。 但是您可以使用选项强制值进入行内(显然有限制)text in row。 从 SQL server 2005 开始,引入了新的 LOB 数据类型,这些新类型:varchar(max), nvarchar(max),varbinary(max)默认情况下存储在行中(当然限制为 8Kb) ..................................................... ………… 完成一张图片。 还有另一种存储在行外的数据,即行溢出数据。 由于此功能,从 2005 年开始,不仅可以定义(就像在 2000 年一样)一些大小总和超过 8060 字节的可变长度列,还可以插入超过此限制的数据,其中一些值将被推送到行外(即该值将存储在行外页面上,并且在 ROW 中只有一个指向存储在行溢出页面上的行的指针): 一个表每行最多可以包含 8,060 个字节。在 SQL Server 2008 中,对包含 varchar、nvarchar、varbinary、sql_variant 或 CLR 用户定义类型列的表放宽了此限制。这些列中每一列的长度仍必须在 8,000 字节的限制范围内;但是,它们的组合宽度可以超过 8,060 字节的限制。这适用于创建和修改 varchar、nvarchar、varbinary、sql_variant 或 CLR 用户定义类型列,也适用于更新或插入数据时。 此限制不适用于 varchar(max)、nvarchar(max)、varbinary(max)、text、image 或 xml 列 (来自超过 8 KB 的行溢出数据) max说明符扩展了 varchar、nvarchar 和 varbinary 数据类型的存储能力。varchar(max)、nvarchar(max) 和 varbinary(max) 统称为大值数据类型。您可以使用大值数据类型来存储最多 2^31-1 字节的数据。 回到这个问题的起源,如何移动 LOB 数据。 当我们谈论将数据移动到另一个文件组时,以及我们在处理 LOB 数据时遇到的困难时,我们指的是 LOB 数据,而不是binary data存储在二进制列(in-row数据)中的数据。 从移动 LOB 数据怎么样?金伯利·L·特里普 在 SQL Server 2012 之前的版本中,无法使用联机操作构建或重建包含 LOB 列的索引。但是,即使使用 OFFLINE 索引构建或重建,现有 LOB 数据也不会移动。一个例外是当您从分区表更改为非分区表时,反之亦然。老实说,围绕 LOB 数据的限制和要求有点奇怪。创建表时可以指定 TEXTIMAGE_ON。这允许该表的 LOB 数据驻留在数据所在的文件组之外。但是,此选项 (TEXTIMAGE_ON) 不适用于 CREATE INDEX 语句。 如果要将 LOBData 移动到另一个文件组怎么办?在 CREATE INDEX 语句期间不允许使用 TEXTIMAGE_ON 选项。因此,如果您想将 LOB 数据移动到与数据不同的另一个文件组,那么“游戏结束”没有导出/导入或使用 INSERT/SELECT 或 SELECT INTO 就无法做到这一点。其中,最好的选择是 INSERT/SELECT,因为您需要先定义表(并且您可以准确地指定数据和 LOB 数据将驻留的位置),然后再复制它。但是,这是一个单一的大型事务,在您迁移时,必须有一些停机时间才能切换所有内容(通过删除原始表并重命名新创建的表)。而且,我什至还没有开始提及如果此表被其他人引用会发生什么。这进一步使这个过程复杂化。 对于你的最后一个问题: 就存储在单独文件组中的二进制数据而言,是否相同 存储 LOB 数据不需要单独的文件组。但是可以使用 TEXTIMAGE_ON 选项单独存储 LOB 数据: TEXTIMAGE_ON { 文件组| "default" } 表示 text、ntext、image、xml、varchar(max)、nvarchar(max)、varbinary(max) 和 CLR 用户定义类型列(包括几何和地理)存储在指定的文件组中。 Varchar(max)、nvarchar(max)、varbinary(max)、xml 和大 UDT 值直接存储在数据行中,最大限制为 8000 字节,只要值适合记录即可。如果该值不适合记录,则将指针按行排序,其余的将存储在 LOB 存储空间中的行外。0 是默认值。TEXTIMAGE_ON 只改变“LOB 存储空间”的位置,不影响数据何时存储在行内。使用 sp_tableoption 的大值类型 out of row 选项将整个 LOB 值存储在行外。 并且固定长度binary数据类型的数据不能存储在单独的文件组中。这是不可能的,因为所有数据都存储在行中,并且在语法上是不可能的 如果表中没有大值列,则不允许 TEXTIMAGE_ON 更多关于 TEXTIMAGE_ON 的信息:CREATE TABLE (Transact-SQL)
根据Technet:数据类型 (Transact-SQL)
所以这些类型被定义为LOB 数据类型。当您询问时,
binary data
我想您是在谈论binary
数据类型的数据。Binary
数据类型可以是以下两种之一:固定长度和可变长度。 具有最大字符数而不是 MAX 说明符的固定长度二进制数据类型或可变长度 varbinary 数据类型在第一种情况下始终存储在行中,在第二种情况下(可能)存储在行外,并且不是 LOB 数据类型。另一方面,根据此分类(来自同一篇 Technet 文章):
varchar(max)
,nvarchar(max)
,text
,ntext
数据类型是CHARACTER字符串而不是 BINARY字符串。所以 LOB 数据类型包括不是二进制字符串的 CHARACTER 字符串。
结论
二进制数据 <> LOB 数据
唯一相同的情况是您的数据定义为 VARBINARY(MAX)
回到关于如何存储 LOB 数据的评论中的问题。
如果该值是旧的遗留类型之一(
text
,ntex
t,image
),则默认情况下将其存储在行外。Off-row 表示数据记录中有一个指针指向存储实际 LOB 值的记录的位置或存储 LOB 值的树的开始:
此图像来自Dmitri Korotkevitch 的 Pro SQL Server Internals 第一版一书。
但是您可以使用选项强制值进入行内(显然有限制)
text in row
。从 SQL server 2005 开始,引入了新的 LOB 数据类型,这些新类型:
varchar(max)
,nvarchar(max)
,varbinary(max)
默认情况下存储在行中(当然限制为 8Kb)..................................................... …………
完成一张图片。
还有另一种存储在行外的数据,即行溢出数据。
由于此功能,从 2005 年开始,不仅可以定义(就像在 2000 年一样)一些大小总和超过 8060 字节的可变长度列,还可以插入超过此限制的数据,其中一些值将被推送到行外(即该值将存储在行外页面上,并且在 ROW 中只有一个指向存储在行溢出页面上的行的指针):
(来自超过 8 KB 的行溢出数据)
回到这个问题的起源,如何移动 LOB 数据。
当我们谈论将数据移动到另一个文件组时,以及我们在处理 LOB 数据时遇到的困难时,我们指的是 LOB 数据,而不是
binary data
存储在二进制列(in-row
数据)中的数据。从移动 LOB 数据怎么样?金伯利·L·特里普
对于你的最后一个问题:
存储 LOB 数据不需要单独的文件组。但是可以使用 TEXTIMAGE_ON 选项单独存储 LOB 数据:
并且固定长度
binary
数据类型的数据不能存储在单独的文件组中。这是不可能的,因为所有数据都存储在行中,并且在语法上是不可能的更多关于 TEXTIMAGE_ON 的信息:CREATE TABLE (Transact-SQL)