Considérations et limitations liées aux tables temporelles

S’applique à : SQL Server 2016 (13.x) et versions ultérieures Base de données Azure SQL Azure SQL Managed Instance

Certaines considérations et limitations doivent être prises en compte quand vous travaillez avec des tables temporelles, en raison de la nature de la gestion système des versions :

  • Une table temporelle doit avoir une clé primaire définie pour pouvoir mettre en corrélation les enregistrements de la table actuelle et ceux la table d’historique. La table d’historique ne peut pas avoir de clé primaire définie.

  • Les colonnes de période SYSTEM_TIME utilisées pour enregistrer les valeurs ValidFrom et ValidTo doivent être définies avec le type de données datetime2.

  • La syntaxe temporelle fonctionne sur les tables ou les vues stockées localement dans la base de données. Avec des objets distants comme des tables sur un serveur lié ou des tables externes, vous ne pouvez pas utiliser la clause FOR ou les prédicats de période directement dans la requête.

  • Si le nom d’une table d’historique est spécifié lors de sa création, vous devez spécifier le nom du schéma et de la table.

  • Par défaut, la table d’historique est compressée par PAGE.

  • Si la table actuelle est partitionnée, la table d’historique est créée sur le groupe de fichiers par défaut, car la configuration du partitionnement n’est pas répliquée automatiquement de la table actuelle vers la table d’historique.

  • Les tables temporelles et d’historique ne peuvent pas utiliser FileTable ou FILESTREAM. FileTable and FILESTREAM autorisent la manipulation des données en dehors de SQL Server. Par conséquent, le contrôle de version du système ne peut pas être garanti.

  • Une table de nœuds ou d’arêtes ne peut pas être créée ou modifiée en tant que table temporelle.

  • Même si les tables temporelles prennent en charge les types de données blob, comme (n)varchar(max), varbinary(max), (n)text et image, ceux-ci entraînent des coûts de stockage importants et ont un impact sur les performances en raison de leur taille. Par conséquent, il convient de prendre des précautions lorsque vous concevez votre système si vous souhaitez utiliser ces types de données .

  • La table d’historique doit être créée dans la même base de données que la table actuelle. L’interrogation temporelle sur un serveur lié n’est pas prise en charge.

  • La table d’historique ne peut pas posséder de contraintes (clé primaire, clé étrangère, table ou colonne).

  • Les vues indexées ne sont pas prises en charge en plus des requêtes temporelles (qui utilisent la clause FOR SYSTEM_TIME).

  • L’option Online (WITH (ONLINE = ON) n’a aucun effet sur ALTER TABLE ALTER COLUMN dans le cas d’une table temporelle avec contrôle de version du système. La colonne ALTER n’est pas effectué en tant qu’opération en ligne, quelle que soit la valeur spécifiée pour l’option ONLINE.

  • Les instructionsINSERT et UPDATE ne peuvent pas faire référence à des colonnes de période SYSTEM_TIME. Les tentatives d’insertion de valeurs directement dans ces colonnes sont bloquées.

  • TRUNCATE TABLE n’est pas pris en charge alors que SYSTEM_VERSIONING est ON.

  • La modification directe des données dans une table d’historique n’est pas autorisée.

  • ON DELETE CASCADE et ON UPDATE CASCADE ne sont pas autorisés sur la table active. En d’autres termes, quand la table temporelle fait référence à la table dans la relation de clé étrangère (correspondant à parent_object_id dans sys.foreign_key), les options CASCADE ne sont pas autorisées. Pour contourner cette limitation, utilisez une logique d’application ou des déclencheurs After pour maintenir la cohérence en cas de suppression dans la table de clé primaire (correspondant à referenced_object_id dans sys.foreign_key). Si la table de clé primaire est temporelle alors que la table de référence ne l’est pas, il n’existe aucune limitation de ce type.
  • Les déclencheurs INSTEAD OF ne sont pas autorisés sur la table actuelle ou sur la table d’historique pour éviter l’invalidation de la logique DML. Les déclencheurs AFTER sont autorisés uniquement dans la table actuelle. Ces déclencheurs sont bloqués dans la table d’historique afin d’éviter l’invalidation de la logique DML.

  • L’utilisation de technologies de réplication est limitée :

    • Groupes de disponibilité : entièrement pris en charge

    • Capture des données modifiées et suivi des modifications : uniquement prise en charge sur la table actuelle

    • Capture instantanée et réplication transactionnelle : uniquement prise en charge pour un serveur de publication unique sans activation de Temporal et un abonné avec Temporal activé. L'utilisation de plusieurs abonnés n'est pas prise en charge en raison d'une dépendance à l'égard de l'horloge du système local, ce qui peut entraîner des données temporelles incohérentes. Dans ce cas, le serveur de publication est utilisé pour une charge de travail OLTP tandis que l’abonné est utilisé pour le déchargement de rapports (avec l’interrogation AS OF). Lorsque l’agent de distribution démarre, il ouvre une transaction qui est maintenue ouverte jusqu’à ce que l’agent de distribution s’arrête. ValidFrom et ValidTo sont renseignés avec l’heure de début de la première transaction démarrée par l’agent de distribution. Il est préférable d’exécuter l’agent de distribution selon une planification et non pas en continu (son comportement par défaut) s’il est important pour votre application ou votre organisation que ValidFrom et ValidTo soient renseignés avec une heure proche de l’heure système actuelle. Pour plus d’informations, voir Scénarios d’usage des tables temporelles.

    • Réplication de fusion : non prise en charge pour les tables temporelles

  • Les requêtes régulières affectent uniquement les données dans la table actuelle. Pour interroger des données dans la table d’historique, vous devez utiliser des requêtes temporelles. Pour plus d’informations, consultez Interroger les données d'une table temporelle version système.

  • Une stratégie d’indexation optimale inclut stockage de colonnes d’index en cluster et/ou un index rowstore d’arbre B dans la table actuelle, et un index columnstore en cluster dans la table d’historique, pour des performances et une taille de stockage optimales. Si vous créez/utilisez votre propre table d’historique, nous vous recommandons vivement de créer ce type d’index comportant des colonnes de période en commençant avec la fin de la colonne. Cet index accélère l’interrogation temporelle et accélère les requêtes qui font partie de la vérification de cohérence des données. La table d’historique par défaut a un index rowstore en cluster créé selon les colonnes de période (début, fin). Nous recommandons au minimum un index rowstore non-cluster.

  • Les objets/propriétés suivantes ne sont pas répliqués de la table actuelle vers la table d’historique lors de la création de la table d’historique :

    • Définition de la période
    • Définition de l’identité
    • Index
    • Statistiques
    • Contraintes de validation
    • Déclencheurs
    • Configuration du partitionnement
    • autorisations
    • Prédicats de sécurité au niveau des lignes
  • Une table d’historique ne peut pas être configurée comme table actuelle d’une chaîne de tables d’historique.

Remarque

De manière générale, la documentation utilise le terme B-tree en référence aux index. Dans les index rowstore, le moteur de base de données implémente une structure B+. Cela ne s’applique pas aux index columnstore ou aux tables à mémoire optimisée. Pour plus d’informations, consultez le Guide de conception et d’architecture d’index SQL Server et Azure SQL.