Organisationsstruktur von Tabellen und Indizes

Tabellen und Indizes werden als eine Auflistung von 8-KB-Seiten gespeichert. In diesem Thema wird die Organisationsstruktur von Tabellen- und Indexseiten beschrieben.

Organisation von Tabellen

Die folgende Abbildung zeigt die Organisationsstruktur einer Tabelle. Eine Tabelle befindet sich in einer oder mehreren Partitionen, und jede Partition enthält Datenzeilen entweder in einer Heap- oder in einer gruppierten Indexstruktur. Die Seiten des Heaps oder des gruppierten Indexes werden je nach den Spaltentypen in den Datenzeilen in einer oder mehreren Zuordnungseinheiten verwaltet.

Tabellenorganisation mit Partitionen

Partitionen

Tabellen- und Indexseiten sind in einer oder mehreren Partitionen enthalten. Eine Partition ist eine benutzerdefinierte Einheit der Datenorganisationsstruktur. Standardmäßig hat jede Tabelle und jeder Index nur eine Partition, in der alle Tabellen- bzw. Indexseiten enthalten sind. Die Partition befindet sich in einer einzigen Dateigruppe. Eine Tabelle oder ein Index mit einer einzigen Partition entspricht der Organisationsstruktur von Tabellen und Indizes in früheren Versionen von SQL Server.

Wenn eine Tabelle oder ein Index mehrere Partitionen verwendet, sind die Daten horizontal partitioniert, sodass Gruppen von Zeilen basierend auf einer angegebenen Spalte einzelnen Partitionen zugeordnet sind. Die Partitionen können sich in einer oder mehreren Dateigruppen in der Datenbank befinden. Die Tabelle oder der Index wird als einzelne logische Entität behandelt, wenn Abfragen oder Aktualisierungen für die Daten ausgeführt werden. Weitere Informationen finden Sie unter Partitionierte Tabellen und Indizes.

Zum Anzeigen der Partitionen, die von einer Tabelle oder einem Index verwendet werden, verwenden Sie die sys.partitions (Transact-SQL)-Katalogsicht.

Gruppierte Tabellen, Heaps und Indizes

SQL Server-Tabellen verwenden eine von zwei möglichen Methoden, um ihre Datenseiten innerhalb einer Partition zu organisieren:

  • Gruppierte Tabellen sind Tabellen, die über einen gruppierten Index verfügen.

    Das Speichern der Datenzeilen erfolgt in der Reihenfolge, die durch den Schlüssel des gruppierten Indexes vorgegeben wird. Der gruppierte Index wird in Form einer B-Baumindexstruktur implementiert, die das schnelle Abrufen der Zeilen auf der Grundlage von Werten des Schlüssels des gruppierten Indexes unterstützt. Die Seiten in jeder Ebene des Indexes, einschließlich der Datenseite auf der Blattebene, sind durch eine doppelt verknüpfte Liste miteinander verknüpft. Die Navigation zwischen den einzelnen Ebenen erfolgt jedoch mithilfe von Schlüsselwerten. Weitere Informationen finden Sie unter Gruppierte Indexstrukturen.

  • Heaps sind Tabellen, die nicht über einen gruppierten Index verfügen.

    Die Datenzeilen werden nicht in einer bestimmten Reihenfolge gespeichert, und es gibt auch keine bestimmte Reihenfolge für die Datenseiten. Die Datenseiten sind nicht in einer verknüpften Liste verknüpft. Weitere Informationen finden Sie unter Heapstrukturen.

Indizierte Sichten weisen dieselbe Speicherstruktur auf wie gruppierte Tabellen.

Wenn ein Heap oder eine gruppierte Tabelle über mehrere Partitionen verfügt, hat jede Partition eine Heap- bzw. eine B-Baumstruktur, in der die Gruppe von Zeilen für die jeweilige Partition enthalten ist. Wenn z. B. eine gruppierte Tabelle über vier Partitionen verfügt, gibt es vier B-Baumstrukturen, d. h. eine in jeder Partition.

Nicht gruppierte Indizes

Nicht gruppierte Indizes weisen eine B-Baumindexstruktur auf, die der Struktur gruppierter Indizes ähnelt. Der Unterschied besteht darin, dass nicht gruppierte Indizes keine Auswirkung auf die Reihenfolge der Datenzeilen haben. Die Blattebene enthält die Indexzeilen. Jede Indexzeile enthält den nicht gruppierten Schlüsselwert, einen Zeilenlokator sowie alle eingeschlossenen Spalten, d. h. Nichtschlüsselspalten. Der Lokator zeigt auf die Datenzeile, in der der Schlüsselwert enthalten ist. Weitere Informationen finden Sie unter Strukturen nicht gruppierter Indizes.

XML-Indizes

Für jede xml-Spalte in der Tabelle können ein primärer und mehrere sekundäre XML-Indizes erstellt werden. Ein XML-Index ist eine aufgeteilte und dauerhafte Darstellung der XML-BLOBs (Binary Large Objects) in der xml-Datentypspalte. XML-Indizes werden als interne Tabellen gespeichert. Zum Anzeigen von Informationen zu XML-Indizes verwenden Sie die Katalogsichten sys.xml_indexes oder sys.internal_tables.

Weitere Informationen zu XML-Indizes finden Sie unter Indizes für Spalten des Datentyps XML.

Zuordnungseinheiten

Eine Zuordnungseinheit ist eine Auflistung von Seiten innerhalb einer Heap- oder B-Baumstruktur, die zum Verwalten von Daten basierend auf ihrem Seitentyp verwendet wird. Die folgende Tabelle zeigt die Typen von Zuordnungseinheiten, die zum Verwalten von Daten in Tabellen und Indizes verwendet werden.

Typ der Zuordnungseinheit

Dient dem Verwalten von

IN_ROW_DATA

Daten- oder Indexzeilen, die alle Daten enthalten, mit Ausnahme von LOB-Daten (Large Object).

Die Seiten besitzen den Typ Daten oder Index.

LOB_DATA

Daten für große Objekte (LOB, Large Object), die in einem oder mehreren der folgenden Datentypen gespeichert sind: text, ntext, image, xml, varchar(max), nvarchar(max), varbinary(max) oder CLR-benutzerdefinierte Typen (CLR UDT, CLR User-Defined Type).

Die Seiten besitzen den Typ Text/Bild.

ROW_OVERFLOW_DATA

Daten variabler Länge, die in varchar-, nvarchar-, varbinary- oder sql_variant-Spalten gespeichert sind, die das Zeilengrößenlimit von 8.060 Byte überschreiten.

Die Seiten besitzen den Typ Text/Bild.

Weitere Informationen zu Seitentypen finden Sie unter Grundlegendes zu Seiten und Blöcken.

Eine Heap- oder B-Struktur kann in einer bestimmten Partition jeweils nur eine Zuordnungseinheit jedes Typs enthalten. Zum Anzeigen der Informationen zu Zuordnungseinheiten von Tabellen oder Indizes verwenden Sie die Katalogsicht sys.allocation_units.

IN_ROW_DATA-Zuordnungseinheit

Für jede Partition, die von einer Tabelle (Heap oder gruppierte Tabelle), von einem Index oder von einer indizierten Sicht verwendet wird, gibt es eine IN_ROW_DATA-Zuordnungseinheit, die aus einer Auflistung von Datenseiten besteht. Diese Zuordnungseinheit enthält auch zusätzliche Auflistungen von Seiten zum Implementieren jedes nicht gruppierten und XML-Indexes, der für die Tabelle oder Sicht definiert ist. Die Seitenauflistungen in jeder Partition einer Tabelle, eines Indexes oder einer indizierten Sicht werden durch Seitenzeiger in der sys.system_internals_allocation_units-Systemsicht verankert.

Wichtiger HinweisWichtig

Die Systemsicht sys.system_internals_allocation_units ist nur für die interne Verwendung durch Microsoft SQL Server reserviert. Zukünftige Kompatibilität wird nicht sichergestellt.

Jede Partition einer Tabelle, eines Indexes oder einer indizierten Sicht hat eine Zeile in sys.system_internals_allocation_units, die eindeutig durch eine Container-ID (container_id) identifiziert ist. Die Container-ID besitzt eine 1:1-Zuordnung zur partition_id in der Katalogsicht sys.partitions, mit der die Beziehung zwischen den in einer Partition gespeicherten Daten der Tabelle, des Indexes oder der indizierten Sicht und den Zuordnungseinheiten bestimmt wird, die zum Verwalten der Daten in der Partition verwendet werden.

Die Zuordnung von Seiten für eine Tabelle, einen Index oder eine indizierte Sicht wird mithilfe verketteter IAM-Seiten verwaltet. Die first_iam_page-Spalte in sys.system_internals_allocation_units zeigt auf die erste IAM-Seite in der Kette der IAM-Seiten, mit denen der Speicher verwaltet wird, der für die Tabelle, den Index oder die indizierte Sicht in der IN_ROW_DATA-Zuordnungseinheit zugeordnet ist.

sys.partitions gibt eine Zeile für jede Partition in einer Tabelle oder in einem Index zurück.

  • Ein Heap hat eine Zeile in sys.partitions, deren index_id = 0 ist.

    Die first_iam_page-Spalte in sys.system_internals_allocation_units zeigt auf die IAM-Kette für die Auflistung von Heapdatenseiten in der angegebenen Partition. Der Server verwendet die IAM-Seiten, um die Seiten in der Auflistung von Datenseiten zu suchen, da diese Seiten nicht miteinander verknüpft sind.

  • Ein gruppierter Index für eine Tabelle oder eine Sicht hat eine Zeile in sys.partitions, deren index_id = 1 ist.

    Die root_page-Spalte in sys.system_internals_allocation_units zeigt auf die oberste Ebene des B-Baums des gruppierten Indexes in der angegebenen Partition. Der Server verwendet den Index-B-Baum, um die Datenseiten in der Partition zu suchen.

  • Ein nicht gruppierter Index, der für eine Tabelle oder eine Sicht erstellt wurde, hat eine Zeile in sys.partitions, deren index_id > 1 ist.

    Die root_page-Spalte in sys.system_internals_allocation_units zeigt auf die oberste Ebene des B-Baums des nicht gruppierten Indexes in der angegebenen Partition.

  • Jede Tabelle, die mindestens eine LOB-Spalte hat, hat auch eine Zeile in sys.partitions, deren index_id > 250 ist.

    Die first_iam_page-Spalte zeugt auf die Kette der IAM-Seiten, mit denen die Seiten in der LOB_DATA-Zuordnungseinheit verwaltet werden.

ROW_OVERFLOW_DATA-Zuordnungseinheit

Für jede Partition, die von einer Tabelle (Heap oder gruppierte Tabelle), von einem Index oder von einer indizierten Sicht verwendet wird, gibt es eine ROW_OVERFLOW_DATA-Zuordnungseinheit. Diese Zuordnungseinheit enthält null (0) Seiten, bis eine Datenzeile mit Spalten variabler Länge (varchar, nvarchar, varbinary oder sql_variant) in der IN_ROW_DATA-Zuordnungseinheit das Zeilengrößenlimit 8 KB übersteigt. Wenn diese Größenbeschränkung erreicht ist, verschiebt SQL Server die Spalte mit der größten Breite aus dieser Zeile zu einer Seite in der ROW_OVERFLOW_DATA-Zuordnungseinheit. Auf der ursprünglichen Seite wird ein 24-Byte-Zeiger zu diesen Daten beibehalten.

Text/Bild-Seiten in der ROW_OVERFLOW_DATA-Zuordnungseinheit werden auf dieselbe Weise verwaltet, wie die Seiten in der LOB_DATA-Zuordnungseinheit verwaltet werden. Das bedeutet, die Text/Bild-Seiten werden durch eine Kette von IAM-Seiten verwaltet.

LOB_DATA-Zuordnungseinheit

Wenn in einer Tabelle oder in einem Index ein oder mehrere LOB-Datentypen enthalten sind, wird eine LOB_DATA-Zuordnungseinheit pro Partition zugeordnet, mit der das Speichern dieser Daten verwaltet wird. Zu den LOB-Datentypen gehören text, ntext, image, xml, varchar(max), nvarchar(max), varbinary(max) und CLR-benutzerdefinierte Typen.

Beispiel für Partition und Zuordnungseinheit

Das folgende Beispiel gibt die Daten für die Partitionen und Zuordnungseinheiten für zwei Tabellen zurück: DatabaseLog, ein Heap mit LOB-Daten und ohne nicht gruppierte Indizes, sowie Currency, eine gruppierte Tabelle ohne LOB-Daten und mit einem nicht gruppierten Index. Beide Tabellen besitzen nur eine einzige Partition.

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;

Im Folgenden wird das Resultset aufgeführt. Beachten Sie, dass die DatabaseLog alle drei Typen von Zuordnungseinheiten verwendet, da die Tabelle sowohl Daten- als auch Text/Bild-Seitentypen enthält. Die Currency-Tabelle enthält keine LOB-Daten, hat aber die Zuordnungseinheit, die zum Verwalten von Daten benötigt wird. Wenn die Currency-Tabelle später geändert wird, um eine Spalte des LOB-Datentyps zu enthalten, wird eine LOB_DATA-Zuordnungseinheit erstellt, um diese Daten zu verwalten.

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)