Organização de tabela e índice

As tabelas e os índices são armazenados como uma coleção de páginas de 8 KB. Este tópico descreve o modo pelo qual as páginas de tabela e índice são organizadas.

Organização da tabela

A ilustração a seguir mostra a organização de uma tabela. Uma tabela é contida em uma ou mais partições e cada partição contém linhas de dados em um heap ou uma estrutura de índice clusterizado. As páginas de heap ou índice clusterizado são gerenciadas em uma ou mais unidades de alocação, dependendo dos tipos de coluna nas linhas de dados.

Organização de tabela com partições

Partições

As páginas de tabela e índice são contidas em uma ou mais partições. Uma partição é uma unidade definida pelo usuário da organização de dados. Por padrão, uma tabela ou um índice tem apenas uma partição que contém todas as páginas de tabela ou índice. A partição reside em um único grupo de arquivos. Uma tabela ou um índice com uma única partição é equivalente à estrutura organizacional de tabelas e índices em versões anteriores do SQL Server.

Quando uma tabela ou índice usa várias partições, os dados são particionados horizontalmente de forma que os grupos de linhas sejam mapeados em partições individuais, com base em uma coluna especificada. As partições podem ser colocadas em um ou mais grupos de arquivos no banco de dados. A tabela ou o índice é tratado como uma única entidade lógica quando são executadas consultas ou atualizações nos dados. Para obter mais informações, consulte Tabelas e índices particionados.

Para exibir as partições usadas por uma tabela ou índice, use a exibição do catálogo sys.partitions (Transact-SQL).

Tabelas, heaps e índices clusterizados

As tabelas do SQL Server usam um dos dois métodos para organizar suas páginas de dados em uma partição:

  • Tabelas clusterizadas são tabelas que têm um índice clusterizado.

    As linhas de dados são armazenadas em ordem com base na chave de índice clusterizado. O índice clusterizado é implementado como uma estrutura de índice da árvore B que oferece suporte à recuperação rápida de linhas, com base em seus valores de chave de índice cluster. As páginas de cada nível do índice, incluindo as páginas de dados no nível folha, são vinculadas a uma lista duplamente vinculada. No entanto, a navegação de um nível para outro é executada usando valores de chave. Para obter mais informações, consulte Estruturas de índice clusterizado.

  • Heaps e tabelas que não têm índice clusterizado.

    As linhas de dados não são armazenadas em nenhuma ordem específica, e não há nenhuma ordem específica para a seqüência das páginas de dados. As páginas de dados não são vinculadas a uma lista vinculada. Para obter mais informações, consulte Estruturas de heap.

Exibições indexadas têm a mesma estrutura de armazenamento que as tabelas clusterizadas.

Quando um heap ou uma tabela clusterizada tem várias partições, cada partição tem uma estrutura de árvore B ou heap que contém o grupo de linhas para aquela partição específica. Por exemplo, se uma tabela clusterizada tiver quatro partições, haverá quatro árvores B; uma em cada partição.

Índices não-clusterizados

Os índices não-clusterizados têm uma estrutura de índice da árvore B semelhante àquela dos índices cluster. A diferença é que os índices não-clusterizados não afetam a ordem das linhas de dados. O nível folha contém linhas de índice. Cada linha de índice contém o valor de chave não-clusterizado, um localizador de linha e qualquer coluna incluída ou não-chave. O localizador aponta para as linhas de dados que têm o valor de chave. Para obter mais informações, consulte Estruturas de índice não clusterizado.

Índices XML

Podem ser criados um índice XML primário e um secundário em cada coluna xml na tabela. Um índice XML é uma representação fragmentada e persistente dos BLOBs (Objetos Binários Grandes) XML na coluna de tipo de dados xml. Os índices XML são armazenados como tabelas internas. Para exibir informações sobre índices xml, use as exibições do catálogo sys.xml_indexes ou sys.internal_tables.

Para obter mais informações sobre índices XML, consulte Índices em colunas de tipo de dados XML.

Unidades de alocação

Uma unidade de alocação é uma coleção de páginas em um heap ou árvore B usada para gerenciar dados com base no tipo da página. A tabela a seguir lista os tipos de unidades de alocação usados para gerenciar dados em tabelas e índices.

Tipo de unidade de alocação

Usado para gerenciar

IN_ROW_DATA

Linhas de dados ou índice que contêm todos os dados, exceto dados de LOB (Objeto Grande).

As páginas são do tipo Dados ou Índice.

LOB_DATA

Dados de objeto grande armazenados em um ou mais tipos de dados: text, ntext, image, xml, varchar(max), nvarchar(max), varbinary(max) ou tipos de dado CLR definidos pelo usuário.

As páginas são do tipo Texto/Imagem.

ROW_OVERFLOW_DATA

Dados de comprimento variável armazenados em colunas varchar, nvarchar, varbinary ou sql_variant que excedem o limite de tamanho de linha de 8.060 bytes.

As páginas são do tipo Texto/Imagem.

Para obter mais informações sobre tipos de página, consulte Compreendendo páginas e extensões.

Um heap ou uma árvore B pode ter apenas uma unidade de alocação de cada tipo em uma partição específica. Para exibir as informações de unidade de alocação da tabela ou do índice, use a exibição do catálogo sys.allocation_units.

Unidade de alocação IN_ROW_DATA

Para toda partição usada por uma tabela (heap ou tabela clusterizada), índice ou exibição indexada, há uma unidade de alocação IN_ROW_DATA constituída de uma coleção de páginas de dados. Essa unidade de alocação também contém coleções adicionais de páginas para implementar cada índice XML e não-clusterizado definido para a tabela ou a exibição. As coleções de páginas em cada partição de uma tabela, índice ou exibição indexada são ancoradas por ponteiros de página na exibição de sistema sys.system_internals_allocation_units.

Observação importanteImportante

A exibição de sistema sys.system_internals_allocation_units é reservada somente para uso interno do MicrosoftSQL Server. A compatibilidade futura não é garantida.

Cada partição de tabela, índice e exibição indexada tem uma linha em sys.system_internals_allocation_units exclusivamente identificada por uma ID de contêiner (container_id). A ID de contêiner tem um mapeamento um para um para o partition_id na exibição do catálogo sys.partitions que mantém a relação entre os dados da tabela, do índice ou da exibição indexada armazenados em uma partição e as unidades de alocação usadas para gerenciar os dados da partição.

A alocação de páginas para uma partição de tabela, índice ou exibição indexada é gerenciada por uma cadeia de páginas IAM. A coluna first_iam_page em sys.system_internals_allocation_units aponta para a primeira página IAM na cadeia de páginas IAM que gerencia o espaço alocado para a tabela, o índice ou a exibição indexada na unidade de alocação IN_ROW_DATA.

O sys.partitions retorna uma linha para cada partição em uma tabela ou índice.

  • Um heap tem uma linha em sys.partitions com index_id = 0.

    A coluna first_iam_page em sys.system_internals_allocation_units aponta para a cadeia IAM da coleção de páginas de dados heap na partição especificada. O servidor usa as páginas IAM para localizar as páginas na coleção de página de dados, pois elas não são vinculadas.

  • Um índice clusterizado em uma tabela ou uma exibição tem uma linha em sys.partitions com index_id = 1.

    A coluna root_page em sys.system_internals_allocation_units aponta para a parte superior da árvore B do índice clusterizado na partição especificada. O servidor usa a árvore B do índice para localizar as páginas de dados na partição.

  • Cada índice não-clusterizado criado para uma tabela ou exibição tem uma linha em sys.partitions com index_id > 1.

    A coluna root_page em sys.system_internals_allocation_units aponta para a parte superior da árvore B do índice não-clusterizado na partição especificada.

  • Cada tabela com pelo menos uma coluna de LOB também tem uma linha em sys.partitions com index_id > 250.

    A coluna first_iam_page aponta para a cadeia de páginas IAM que gerenciam as páginas na unidade de alocação LOB_DATA.

Unidade de alocação ROW_OVERFLOW_DATA

Para toda partição usada por uma tabela (heap ou tabela clusterizada), índice ou exibição indexada, há uma unidade de alocação IN_OVERFLOW_DATA. Essa unidade de alocação contém zero (0) página até que uma linha de dados com colunas de comprimento variável (varchar, nvarchar, varbinary ou sql_variant) na unidade de alocação IN_ROW_DATA exceda o limite de tamanho de linha de 8 KB. Quando o limite de tamanho é alcançado, o SQL Server move a coluna com a largura maior daquela linha para uma página na unidade de alocação ROW_OVERFLOW_DATA. Um ponteiro de 24 bytes para esses dados fora da linha é mantido na página original.

As páginas de Texto/Imagem na unidade de alocação ROW_OVERFLOW_DATA são gerenciadas da mesma maneira que as páginas na unidade de alocação LOB_DATA. Ou seja, as páginas de Texto/Imagem são gerenciadas por uma cadeia de páginas IAM.

Unidade de alocação LOB_DATA

Quando uma tabela ou índice tem um ou mais tipos de dados de LOB, uma unidade de alocação LOB_DATA por partição é alocada para gerenciar o armazenamento de tais dados. Os tipos de dados de LOB incluem text, ntext, image, xml, varchar(max), nvarchar(max), varbinary(max) e tipos de dado CLR definidos pelo usuário.

Exemplo de partição e unidade de alocação

O exemplo a seguir retorna dados de partição e unidade de alocação para duas tabelas: DatabaseLog, um heap com dados de LOB e nenhum índice não-clusterizado, e Currency, uma tabela clusterizada sem dados de LOB e um índice não-clusterizado. Ambas as tabelas têm uma única partição.

USE AdventureWorks;
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;

Aqui está o conjunto de resultados. Observe que a tabela DatabaseLog usa todos os três tipos de unidade de alocação, pois contém dados e tipos de página de Texto/Imagem. A tabela Currency não tem dados de LOB, mas tem a unidade de alocação exigida para gerenciar páginas de dados. Se a tabela Currency for modificada posteriormente para incluir uma coluna de tipo de dados de LOB, uma unidade de alocação LOB_DATA será criada para gerenciar tais dados.

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)