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 valeursValidFrom
etValidTo
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 surALTER TABLE ALTER COLUMN
dans le cas d’une table temporelle avec contrôle de version du système. La colonneALTER
n’est pas effectué en tant qu’opération en ligne, quelle que soit la valeur spécifiée pour l’optionONLINE
.Les instructions
INSERT
etUPDATE
ne peuvent pas faire référence à des colonnes de périodeSYSTEM_TIME
. Les tentatives d’insertion de valeurs directement dans ces colonnes sont bloquées.TRUNCATE TABLE
n’est pas pris en charge alors queSYSTEM_VERSIONING
estON
.La modification directe des données dans une table d’historique n’est pas autorisée.
ON DELETE CASCADE
etON 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
danssys.foreign_key
), les optionsCASCADE
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
danssys.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éclencheursAFTER
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
etValidTo
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 queValidFrom
etValidTo
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.
Contenu connexe
- Tables temporelles
- Bien démarrer avec les tables temporelles avec versions gérées par le système
- Vérifications de cohérence système des tables temporelles
- Partition avec des tables temporelles
- Sécurité de la table temporelle
- Gérer la rétention des données d'historique dans les tables temporelles avec contrôle de version par le système
- Tables temporelles avec version gérée par le système avec tables à mémoire optimisée
- Vues et fonctions des métadonnées des tables temporelles