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 valores ValidFrom e ValidTo 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 em ALTER TABLE ALTER COLUMN em uma tabela temporal com versão do sistema. A coluna ALTER não é executada como uma operação online, independentemente de qual valor foi especificado para a opção ONLINE.

  • As instruções INSERT e UPDATE não podem fazer referência às colunas de período SYSTEM_TIME. As tentativas de inserir valores diretamente nessas colunas são bloqueadas.

  • TRUNCATE TABLE não tem suporte enquanto SYSTEM_VERSIONING é ON.

  • Não é permitida a modificação direta dos dados em uma tabela de histórico.

  • Não é permitido ter ON DELETE CASCADE e ON UPDATE CASCADE na tabela atual. Em outras palavras, quando a tabela temporal estiver fazendo referência à tabela na relação de chave estrangeira (correspondente a parent_object_id em sys.foreign_key), as opções CASCADE 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 ao referenced_object_id em sys.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 gatilhos AFTER 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 e ValidTo 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 ter ValidFrom e ValidTo 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.