在讨论不同类型的页面前,需要了解以下系统视图之间的关系:sys.objects, sys.partitions, sys.allocation_units and sys.system_internals_allocation_units
Case 1 (simple table with record size less than 8000 bytes and no LOB data) :
When a table is created (Heap), by default all its pages are aligned in one partition. Partition is a unit of data organization.
当表创建时,默认其所有页面分配在一个分区(分区是组织数据的单位),添加了非聚集索引,分区框架和与其相关的索引页面逻辑上分配到各自的分区。基于存储的数据,一个分区有3种类型的页组面:IN_ROW_DATA页,ROW_OVERFLOW_DATA页和LOB_DATA页,这些页组也称为“分配单位”。
以下是它们的区别:
1. IN_ROW_DATA (默认) : 若一个表设计简单(即行记录小于8000字节,不存在LOB数据类型),页中存储的所有数据以IN_ROW_DATA标记。
2. ROW_OVERFLOW_DATA :若表中包含3个varchar(4000)的数据类型,当插入大于8000字节的记录时,其数据将移动到ROW_OVERFLOW_DATA页。
3. LOB_DATA : LOB数据不与数据页一起存储,LOB数据存储在LOB_DATA的特殊页,数据页包含16字节的指针用于查找LOB_DATA页面。
下面通过创建一个示例表(其表记录小于8000字节,不包含LOB数据类型)
CREATE TABLE tExample1(
strEmpCode char(6),
strName varchar(100),
strDept varchar(10),
strCity varchar(100))
GO
以下查询输出表对象的相关信息:
select object_id, name, type_desc from sys.objects where name = 'tExample1'
go
示例输出:
object_id name type_desc
2089058478 tExample1 USER_TABLE
正如前面提到的,表逻辑上分配在一个容器(也叫做“分区”),以下查询输出tExample1表对象的分区信息:
select object_name(object_id), object_id, partition_id, hobt_id, partition_number, rows
from sys.partitions
where object_name(object_id) = 'tExample1'
go
示例输出:
TableName object_id partition_id hobt_id partition_number rows
tExample1 2089058478 72057594038648800 72057594038648800 1 0
Object_id : 表对象标识
Partition_id : 表对象的分区标识
Hobt_id : 存储数据的heap或B树的标识
提示:一张表有一个或多个分区,每一个分区最大有3种分区单元
以下查询输出分区编号为72057594038648800的Allocation_unit详细信息
select *
from sys.allocation_units
where container_id = 72057594038648832
go
allocation_unit_id type type_desc container_id data_space_id total_pages used_pages data_pages
72057594042646500 1 IN_ROW_DATA 72057594038648800 1 0 0 0
下面用一条查询输出:
select so.name, so.object_id, sp.index_id, sp.partition_id, sp.hobt_id, sa.allocation_unit_id, sa.type_desc, sa.total_pages
from sys.objects so
inner join sys.partitions sp on so.object_id = sp.object_id
inner join sys.allocation_units sa on sa.container_id = sp.hobt_id
where so.name = 'tExample1'
go
Sample output :
name object_id index_id partition_id hobt_id allocation_unit_id type_desc total_pages
tExample1 2089058478 0 72057594038648800 72057594038648800 72057594042646500 IN_ROW_DATA 0
Case 2:
本例详细描述对象Object,分区 Partition 和分配单位Allocation_unit 的概念
首先创建包含LOB列且行大小大于8000的表
create table tExample2(
strId int identity(1,1) PRIMARY KEY,
strdeptcode char(10),
strComment1 varchar(4000),
strComment2 varchar(4000),
strComment3 varchar(4000),
strLongText varchar(max))
go
创建非聚集索引:
create nonclustered index nci_tExample2_strdeptcode on tExample2(strDeptCode)
go
接着插入2条记录:
insert into tExample2(strDeptCode, strComment1, strComment2, strComment3, strLongText)
values('DEPT01',replicate('a',4000),replicate('b',4000), replicate('c',4000), replicate('d',10000))
GO 2
以下查询将输出所有分区的信息:
select so.name, so.object_id, sp.index_id, sp.partition_id, sp.hobt_id, sa.allocation_unit_id, sa.type_desc, sa.total_pages
from sys.objects so
inner join sys.partitions sp on so.object_id = sp.object_id
inner join sys.allocation_units sa on sa.container_id = sp.hobt_id
where so.name = 'tExample2'
go
name object_id index_id partition_id hobt_id allocation_unit_id type_desc total_pages
tExample2 277576027 1 72057594039173120 72057594039173120 72057594040352768 IN_ROW_DATA 4
tExample2 277576027 1 72057594039173120 72057594039173120 72057594040483840 LOB_DATA 3
tExample2 277576027 1 72057594039173120 72057594039173120 72057594040418304 ROW_OVERFLOW_DATA 3
tExample2 277576027 2 72057594039238656 72057594039238656 72057594040549376 IN_ROW_DATA 2
说明:
Name: 表对象名称
Object_id: 表对象标识
Index_id: 1为聚集索引,2为非聚集索引
Partition_id, hobt_id:由于表存在聚集索引和非聚集索引,所以有两个分区标识
Allocation_unit_id: 聚集索引分区包含3个分配单元,非聚集索引分区包含1个分配单元
Total_pages: 页数
下面描述上面的结构:
小结:
本篇文章我们介绍了表、分区及分配单元间的关系,也说明了具有多个分区或分配单元的数据的组织方式。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/355374/viewspace-683202/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/355374/viewspace-683202/