Considerações e limitações da tabela temporal
Aplica-se a: SQL Server 2016 (13.x) e posterior Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure
Há algumas considerações e limitações a serem consideradas ao trabalhar com tabelas temporais, devido à natureza do controle de versão do sistema:
Uma tabela temporal deve ter uma chave primária definida para correlacionar registros entre a tabela atual e a tabela de histórico. A tabela de histórico não pode ter uma chave primária definida.
As colunas de período
SYSTEM_TIME
usadas para registrar os valoresValidFrom
eValidTo
devem ser definidas com um tipo de dados de datetime2.A sintaxe temporal funciona em tabelas ou exibições armazenadas localmente no banco de dados. Com objetos remotos, como tabelas em um servidor vinculado ou tabelas externas, você não pode usar a cláusula
FOR
ou predicados de período diretamente na consulta.Se o nome de uma tabela de histórico estiver especificado durante a criação da tabela de histórico, você deverá especificar o nome do esquema e da tabela.
Por padrão, a tabela de histórico é compactada por
PAGE
.Se a tabela atual estiver particionada, a tabela de histórico será criada no grupo de arquivo padrão porque a configuração de particionamento não será replicada automaticamente da tabela atual para a tabela de histórico.
As tabelas temporais e de histórico não podem usar FileTable ou FILESTREAM. FileTable e FILESTREAM permitem a manipulação de dados fora do SQL Server e, portanto, o controle de versão do sistema não pode ser garantido.
Uma tabela de nó ou borda não pode ser criada como ou alterada para uma tabela temporal.
Embora as tabelas temporais ofereçam suporte a tipos de dados de blobs, como (n)varchar(max), varbinary(max), (n)text e image, elas gerarão custos significativos de armazenamento e terão implicações de desempenho devido a seu tamanho. Assim, ao criar seu sistema, tome cuidado ao usar esses tipos de dados.
A tabela de histórico deve ser criada no mesmo banco de dados da tabela atual. As consultas temporais nos servidores vinculados não têm suporte.
A tabela de histórico não pode ter restrições (restrições de chave primária, chave estrangeira, tabela ou coluna).
Não há compatibilidade das exibições indexadas em consultas temporais (consultas que usam a cláusula
FOR SYSTEM_TIME
).A opção online (
WITH (ONLINE = ON
) não tem nenhum efeito emALTER TABLE ALTER COLUMN
em uma tabela temporal com versão do sistema. A colunaALTER
não é executada como uma operação online, independentemente de qual valor foi especificado para a opçãoONLINE
.As instruções
INSERT
eUPDATE
não podem fazer referência às colunas de períodoSYSTEM_TIME
. As tentativas de inserir valores diretamente nessas colunas são bloqueadas.TRUNCATE TABLE
não tem suporte enquantoSYSTEM_VERSIONING
éON
.Não é permitida a modificação direta dos dados em uma tabela de histórico.
- Não é permitido ter
ON DELETE CASCADE
eON UPDATE CASCADE
na tabela atual. Em outras palavras, quando a tabela temporal estiver fazendo referência à tabela na relação de chave estrangeira (correspondente aparent_object_id
emsys.foreign_key
), as opçõesCASCADE
não serão permitidas. Para trabalhar com essa limitação, use a lógica do aplicativo ou gatilhos AFTER para manter a consistência de exclusão na tabela de chave primária (correspondente aoreferenced_object_id
emsys.foreign_key
). Se a tabela de chave primária for temporal e a tabela de referência não for temporal, não haverá essa limitação.
Para evitar invalidar a lógica de DML, não é permitido ter os gatilhos
INSTEAD OF
na tabela atual ou de histórico. Só é permitido usar os gatilhosAFTER
na tabela atual. Esses gatilhos são bloqueados na tabela de histórico para evitar a anulação da lógica de DML.O uso de tecnologias de replicação é limitado:
Grupos de Disponibilidade: suporte completo
Captura de dados de alterações e controle de alterações: suporte apenas na tabela atual
Instantâneo e replicação transacional: com suporte apenas para um único publicador sem o temporal habilitado e um assinante com o temporal habilitado. Não há suporte ao uso de vários assinantes devido a uma dependência do relógio do sistema local, o que poderia levar a dados temporais inconsistentes. Nesse caso, o editor é usado para uma carga de trabalho OLTP, enquanto o assinante serve para o descarregamento de relatórios (incluindo consulta
AS OF
). Quando o agente de distribuição é iniciado, ele abre uma transação que é mantida aberta até o agente de distribuição parar.ValidFrom
eValidTo
são preenchidos com a hora de início da primeira transação que o agente de distribuição inicia. Talvez seja preferível executar o agente de distribuição conforme uma agenda, em vez de usar o comportamento padrão de executá-lo continuamente, se terValidFrom
eValidTo
preenchidos com um horário próximo ao horário atual do sistema for importante para seu aplicativo ou organização. Para saber mais, consulte Cenários de uso de tabela temporal.Replicação de mesclagem: não tem suporte para tabelas temporais
As consultas comuns afetam somente os dados na tabela atual. Para consultar os dados na tabela de histórico, você deverá usar consultas temporais. Para obter mais informações, confira Consultar dados em uma tabela temporal com controle da versão do sistema.
Uma estratégia de indexação ideal inclui um índice de repositório com colunas clusterizadas e/ou um índice de rowstore de árvore B na tabela atual e um índice columnstore clusterizado na tabela de histórico para proporcionar níveis ideais de desempenho e tamanho do armazenamento. Se você criar/usar sua própria tabela de histórico, será altamente recomendável que você crie esse tipo de índice com colunas de período começando com o final da coluna do período. Esse índice acelera a consulta temporal e acelera as consultas que fazem parte da verificação de consistência de dados. A tabela de histórico padrão tem um índice rowstore clusterizado criado para você com base nas colunas de período (início, fim). No mínimo, recomenda-se um índice rowstore não clusterizado.
Os seguintes objetos/propriedades não serão replicados da tabela atual para a tabela de histórico quando a tabela de histórico for criada:
- Definição de período
- Definição de identidade
- Índices
- Estatísticas
- Verificar restrições
- Gatilhos
- Configuração de particionamento
- Permissões
- Predicados de segurança em nível de linha
Uma tabela de histórico não pode ser configurada como tabela atual em uma cadeia de tabelas de histórico.
Observação
A documentação usa o termo árvore B geralmente em referência a índices. Em índices de rowstore, o Database Engine implementa uma árvore B+. Isso não se aplica a índices columnstore ou índice em tabelas com otimização de memória. Para obter mais informações, confira o Guia de arquitetura e design do índice do SQL Server e SQL do Azure.
Conteúdo relacionado
- Tabelas temporais
- Introdução a tabelas temporais com controle de versão do sistema
- Verificações de consistência do sistema de tabela temporal
- Partição com tabelas temporais
- Segurança da tabela temporal
- Gerenciar a retenção de dados históricos em tabelas temporárias com versão do sistema
- Tabelas temporais com controle de versão do sistema e tabelas com otimização de memória
- Exibições e funções de metadados de tabela temporal