Организация таблиц и индексов

Таблицы и индексы хранятся в виде коллекции страниц размером 8 КБ. В этом подразделе описывается способ организации страниц таблиц и индексов.

Организация таблиц

Следующая иллюстрация показывает организацию таблицы. Таблица содержится в одной или нескольких секциях, а каждая секция содержит строки данных либо в куче, либо в структуре кластеризованного индекса. Страницы кучи или кластеризованного индекса объединяются в одну или несколько единиц распределения в зависимости от типов столбцов в строках данных.

Структура таблиц с секциями

Секции

Страницы таблиц и индексов содержатся в одной или нескольких секциях. Секция — это пользовательская единица организации данных. По умолчанию таблица или индекс имеет единственную секцию, которая содержит все страницы таблицы или индекса. Секция располагается в одной файловой группе. Таблица или индекс, имеющие одну секцию, эквивалентны организационной структуре таблиц и индексов предыдущих версий SQL Server.

Если таблица или индекс используют несколько секций, данные разделяются горизонтально, так что группы строк сопоставляются отдельным секциям, основываясь на указанном столбце. Секции могут храниться в одной или нескольких файловых группах в базе данных. Таблица или индекс рассматриваются как единая логическая сущность при выполнении над данными запросов или обновлений. Дополнительные сведения см. в разделе Секционированные таблицы и индексы.

Для просмотра секций, используемых таблицей или индексом, можно воспользоваться представлением каталога sys.partitions (Transact-SQL).

Кластеризованные таблицы, кучи и индексы

Таблицы SQL Server используют один из двух методов организации страниц данных внутри секции.

  • Кластеризованные таблицы — это таблицы, имеющие кластеризованный индекс.

    Строки данных хранятся по порядку ключа кластеризованного индекса. Кластеризованный индекс реализуется в виде структуры индекса сбалансированного дерева, которая поддерживает быстрый поиск строк по их ключевым значениям в кластеризованном индексе. Страницы в каждом уровне индекса, включая страницы данных на конечном уровне, связаны в двунаправленный список. Однако перемещение из одного уровня на другой выполняется при помощи ключевых значений. Дополнительные сведения см. в разделе Структуры кластеризованного индекса.

  • Кучи — это таблицы, которые не имеют кластеризованного индекса.

    Строки данных хранятся без определенного порядка, и какой-либо порядок в последовательности страниц данных отсутствует. Страницы данных не связаны в связный список. Дополнительные сведения см. в разделе Структуры кучи.

Индексированные представления имеют такую же структуру хранения, что и кластеризованные таблицы.

Если куча или кластеризованная таблица содержит несколько секций, каждая секция имеет структуру кучи или сбалансированного дерева, содержащую группу строк для указанной секции. Например, если кластеризованная таблица содержит четыре секции, то имеется четыре сбалансированных дерева, по одному на каждую секцию.

Некластеризованные индексы

Некластеризованные индексы имеют индексную структуру сбалансированного дерева, схожую со структурой кластеризованных индексов. Различие состоит в том, что некластеризованные индексы не влияют на порядок строк данных. Конечный уровень содержит строки индекса. Каждая строка индекса содержит некластеризованное ключевое значение, указатель строки и любые включенные или неключевые столбцы. Указатель ссылается на строку данных, которая имеет ключевое значение. Дополнительные сведения см. в разделе Структуры некластеризованных индексов.

XML-индексы

Для каждого столбца xml в таблице могут быть созданы один первичный и несколько вторичных XML-индексов. XML-индекс представляет собой разделенное и сохраненное представление больших двоичных объектов XML (BLOB) в столбце типа данных xml. XML-индексы хранятся во внутренних таблицах. Для просмотра сведений об XML-индексах можно воспользоваться представлениями каталогов sys.xml_indexes и sys.internal_tables.

Дополнительные сведения об XML-индексах см. в разделе Индексы для столбцов типа данных xml.

Единицы распределения

Единица распределения — это коллекция страниц в куче или сбалансированном дереве, используемая для управления данными на основании типов страниц. В следующей таблице перечисляются единицы распределения, используемые для управления данными в таблицах и индексах.

Тип единицы распределения

Данные, для управления которыми этот тип используется

IN_ROW_DATA

Строки данных или индекса, которые содержат все данные, кроме данных больших объектов (LOB).

Страницы имеют тип Data или Index.

LOB_DATA

Данные большого объекта, хранимые в одном или нескольких из следующих типов данных: text, ntext, image, xml, varchar(max), nvarchar(max), varbinary(max) или определяемые пользователем типы CLR (CLR UDT).

Страницы имеют тип Text/Image.

ROW_OVERFLOW_DATA

Данные переменной длины, хранящиеся в столбцах типов varchar, nvarchar, varbinary или sql_variant, которые превышают ограничение размера строки, равное 8 060 байт.

Страницы имеют тип Text/Image.

Дополнительные сведения о типах страниц см. в разделе Страницы и экстенты.

Куча или сбалансированное дерево могут иметь лишь одну единицу распределения каждого типа в отдельной секции. Для просмотра сведений о единице распределения таблицы или индекса можно воспользоваться представлением каталога sys.allocation_units.

Единица распределения IN_ROW_DATA

Для каждой секции, используемой таблицей (кучей или кластеризованной таблицей), индексом или индексированным представлением, существует одна единица распределения IN_ROW_DATA, которая состоит из коллекции страниц данных. Эта единица распределения также содержит дополнительные коллекции страниц для реализации каждого некластеризованного индекса и XML-индекса, определенного для таблицы или представления. Коллекции страниц в каждой секции таблицы, индекса или индексированного представления закреплены указателями страницы в системном представлении sys.system_internals_allocation_units.

Важное примечаниеВажно!

Системное представление sys.system_internals_allocation_units зарезервировано только для внутреннего использования Microsoft SQL Server. Совместимость с будущими версиями не гарантируется.

Каждой секции таблицы, индекса и индексированного представления отвечает одна строка в представлении sys.system_internals_allocation_units, уникально определенная идентификатором контейнера (container_id). Идентификатор контейнера однозначно сопоставлен с идентификатором partition_id в представлении каталога sys.partitions, которое поддерживает связь между данными таблицы, индекса или индексированного представления, хранящимися в секции, и единицами распределения, используемыми для управления данными внутри секции.

Размещение страниц в секции таблицы, индекса или индексированного представления управляется цепочкой IAM-страниц. Столбец first_iam_page представления sys.system_internals_allocation_units указывает на первую IAM-страницу в цепочке IAM-страниц, управляющую пространством, выделенным для таблицы, индекса или индексированного представления в единице распределения IN_ROW_DATA.

Представление каталога sys.partitions возвращает по одной строке для каждой секции в таблице или индексе.

  • Куча имеет строку в представлении каталога sys.partitions с index_id = 0.

    Столбец first_iam_page в представлении sys.system_internals_allocation_units указывает на цепочку IAM для коллекции страниц данных кучи в указанной секции. Сервер использует IAM-страницы, чтобы найти страницы в коллекции страниц данных, так как они не связаны.

  • Кластеризованный индекс для таблицы или представления имеет одну строку в представлении sys.partitions с index_id = 1.

    Столбец root_page в представлении sys.system_internals_allocation_units указывает на вершину сбалансированного дерева кластеризованного индекса в указанной секции. Сервер использует индекс сбалансированного дерева для поиска страниц данных в секции.

  • Каждый некластеризованный индекс, созданный для таблицы или представления, имеет одну строку в представлении sys.partitions с index_id > 1.

    Столбец root_page в представлении sys.system_internals_allocation_units указывает на вершину сбалансированного дерева некластеризованного индекса в указанной секции.

  • Каждая таблица, в которой есть по крайней мере один столбец LOB, имеет строку в представлении каталога sys.partitions с index_id > 250.

    Столбец first_iam_page указывает на цепочку IAM-страниц, которая управляет страницами в единице распределения LOB_DATA.

Единица распределения ROW_OVERFLOW_DATA

Для каждой секции, используемой таблицей (кучей или кластеризованной таблицей), индексом или индексированным представлением, существует единица распределения ROW_OVERFLOW_DATA. Эта единица распределения содержит ноль (0) страниц до тех пор, пока строка данных со столбцами переменной длины (varchar, nvarchar, varbinary или sql_variant) в единице распределения IN_ROW_DATA не превышает ограничение размера строки 8 КБ. По достижении границы размера SQL Server перемещает столбец с наибольшей шириной из данной строки на страницу в единице распределения ROW_OVERFLOW_DATA. Указатель на эти внестрочные данные, имеющий длину 24 бита, сохраняется на начальной странице.

Страницы Text/Image в единице распределения ROW_OVERFLOW_DATA управляются таким же образом, что и страницы в единице распределения LOB_DATA. Таким образом, страницы Text/Image управляются цепочкой IAM-страниц.

Единица распределения LOB_DATA

Если таблица или индекс имеют несколько типов данных LOB, для управления хранением данных выделяется по одной единице распределения LOB_DATA для каждой секции. Типы данных LOB включают text, ntext, image, xml, varchar(max), nvarchar(max), varbinary(max) или определяемые пользователем типы CLR (CLR UDT).

Пример секции и единицы распределения

Следующий пример возвращает секцию и данные единицы распределения для двух таблиц: DatabaseLog, куча с данными LOB и некластеризованными индексами, и Currency, кластеризованная таблица без данных LOB и одним некластеризованным индексом. Обе таблицы имеют единственную секцию.

USE AdventureWorks2008R2;
GO
SELECT o.name AS table_name,p.index_id, i.name AS index_name , au.type_desc AS allocation_type, au.data_pages, partition_number
FROM sys.allocation_units AS au
    JOIN sys.partitions AS p ON au.container_id = p.partition_id
    JOIN sys.objects AS o ON p.object_id = o.object_id
    JOIN sys.indexes AS i ON p.index_id = i.index_id AND i.object_id = p.object_id
WHERE o.name = N'DatabaseLog' OR o.name = N'Currency'
ORDER BY o.name, p.index_id;

Ниже приведен результирующий набор. Обратите внимание на то, что таблица DatabaseLog использует все три типа единиц распределения, так как она содержит страницы типов Data и Text/Image. Таблица Currency не содержит данных LOB, но имеет единицу распределения, необходимую для управления страницами данных. Если таблица Currency будет изменена и будет включать столбец типа данных LOB, то будет создана единица распределения LOB_DATA для управления этими данными.

table_name  index_id index_name               allocation_type     data_pages  partition_number 
----------- -------- -----------------------  ---------------     -----------  ------------
Currency    1        PK_Currency_CurrencyCode IN_ROW_DATA         1           1
Currency    3        AK_Currency_Name         IN_ROW_DATA         1           1
DatabaseLog 0        NULL                     IN_ROW_DATA         160         1
DatabaseLog 0        NULL                     ROW_OVERFLOW_DATA   0           1
DatabaseLog 0        NULL                     LOB_DATA            49          1
(5 row(s) affected)