Vous pensez à une conception de base de données pour la journalisation d'audit ? Rappelez-vous ce qui est arrivé à Hansel et Gretel :ils pensaient que laisser une simple trace de chapelure était un bon moyen de retracer leurs pas.
Lorsque nous concevons un modèle de données, nous sommes formés pour appliquer la philosophie selon laquelle maintenant est tout ce qui existe . Par exemple, si nous concevons un schéma pour stocker les prix d'un catalogue de produits, nous pouvons penser que la base de données n'a besoin que de nous indiquer le prix de chaque produit à l'instant présent. Mais si nous voulions savoir si les prix ont été modifiés et, si oui, quand et comment ces modifications se sont produites, nous serions en difficulté. Bien sûr, nous pourrions concevoir la base de données spécifiquement pour conserver un enregistrement chronologique des modifications - communément appelé piste d'audit ou journal d'audit.
La journalisation d'audit permet à une base de données d'avoir une "mémoire" des événements passés. En continuant avec l'exemple de liste de prix, un journal d'audit approprié permettra à la base de données de nous dire exactement quand un prix a été mis à jour, quel était le prix avant qu'il ne soit mis à jour, qui l'a mis à jour et d'où.
Solutions de journalisation d'audit de base de données
Ce serait formidable si la base de données pouvait conserver un instantané de son état pour chaque changement qui se produit dans ses données. De cette façon, vous pouvez revenir à n'importe quel moment et voir comment les données étaient à ce moment précis, comme si vous rembobiniez un film. Mais cette façon de générer la journalisation d'audit est évidemment impossible; le volume d'informations qui en résulterait et le temps qu'il faudrait pour générer les logs seraient trop élevés.
Les stratégies de journalisation d'audit sont basées sur la génération de pistes d'audit uniquement pour les données qui peuvent être supprimées ou modifiées. Toute modification doit être auditée pour annuler les modifications, interroger les données dans les tables d'historique ou suivre les activités suspectes.
Il existe plusieurs techniques de journalisation d'audit populaires, mais aucune d'entre elles ne sert à tous les objectifs. Les plus efficaces sont souvent coûteux, gourmands en ressources ou dégradent les performances. D'autres sont moins chers en termes de ressources mais sont soit incomplets, encombrants à entretenir, soit nécessitent un sacrifice dans la qualité de la conception. La stratégie que vous choisirez dépendra des exigences de l'application et des limites de performances, des ressources et des principes de conception que vous devez respecter.
Solutions de journalisation prêtes à l'emploi
Ces solutions de journalisation d'audit fonctionnent en interceptant toutes les commandes envoyées à la base de données et en générant un journal des modifications dans un référentiel séparé. Ces programmes offrent plusieurs options de configuration et de rapport pour suivre les actions des utilisateurs. Ils peuvent consigner toutes les actions et requêtes envoyées à une base de données, même lorsqu'elles proviennent d'utilisateurs disposant des privilèges les plus élevés. Ces outils sont optimisés pour minimiser l'impact sur les performances, mais cela a souvent un coût monétaire.
Le prix des solutions de piste d'audit dédiées peut se justifier si vous manipulez des informations très sensibles (telles que des dossiers médicaux) où toute altération des données doit être parfaitement surveillée et auditable et la piste d'audit doit être inaltérable. Mais lorsque les exigences de piste d'audit ne sont pas aussi strictes, le coût d'une solution de journalisation dédiée peut être excessif.
Les outils de surveillance natifs proposés par les systèmes de bases de données relationnelles (SGBDR) peuvent également être utilisés pour générer des pistes d'audit. Les options de personnalisation permettent de filtrer les événements enregistrés, afin de ne pas générer d'informations inutiles ou de surcharger le moteur de base de données avec des opérations de journalisation qui ne seront pas utilisées ultérieurement. Les journaux ainsi générés permettent un suivi détaillé des opérations exécutées sur les tables. Cependant, ils ne sont pas utiles pour interroger les tables d'historique, car ils n'enregistrent que les événements.
L'option la plus économique pour conserver une piste d'audit consiste à concevoir spécifiquement votre base de données pour la journalisation d'audit. Cette technique est basée sur des tables de log qui sont remplies par des déclencheurs ou des mécanismes spécifiques à l'application qui met à jour la base de données. Il n'existe pas d'approche universellement acceptée pour la conception de bases de données de journalisation d'audit, mais il existe plusieurs stratégies couramment utilisées, chacune ayant ses avantages et ses inconvénients.
Techniques de conception de journaux d'audit de base de données
Gestion des versions de ligne pour la journalisation d'audit en place
Une façon de conserver une piste d'audit pour une table consiste à ajouter un champ qui indique le numéro de version de chaque enregistrement. Les insertions dans la table sont enregistrées avec un numéro de version initial. Toutes les modifications ou suppressions deviennent en fait des opérations d'insertion, où de nouveaux enregistrements sont générés avec les données mises à jour et le numéro de version est incrémenté de un. Vous pouvez voir un exemple de cette conception de journalisation d'audit sur place ci-dessous :
Remarque :les conceptions de table avec gestion des versions de ligne intégrée ne peuvent pas être liées par des relations de clé étrangère.
En plus du numéro de version, certains champs supplémentaires doivent être ajoutés au tableau pour déterminer l'origine et la cause de chaque modification apportée à un enregistrement :
- La date/l'heure à laquelle la modification a été enregistrée.
- L'utilisateur et l'application.
- L'action effectuée (insertion, mise à jour, suppression), etc. Pour que la piste d'audit soit efficace, le tableau doit uniquement prendre en charge les insertions (les mises à jour et les suppressions ne doivent pas être autorisées). La table nécessite également nécessairement une clé primaire de substitution, car toute autre combinaison de champs sera sujette à répétition.
Pour accéder aux données de table mises à jour via des requêtes, vous devez créer une vue qui renvoie uniquement la dernière version de chaque enregistrement. Ensuite, vous devez remplacer le nom de la table par le nom de la vue dans toutes les requêtes sauf celles spécifiquement destinées à visualiser la chronologie des enregistrements.
L'avantage de cette option de gestion des versions est qu'elle ne nécessite pas l'utilisation de tables supplémentaires pour générer la piste d'audit. De plus, seuls quelques champs sont ajoutés aux tables auditées. Mais cela a un énorme inconvénient :cela vous obligera à commettre certaines des erreurs de conception de base de données les plus courantes. Il s'agit notamment de ne pas utiliser l'intégrité référentielle ou les clés primaires naturelles lorsque cela est nécessaire, ce qui rend impossible l'application des principes de base de la conception de diagrammes entité-relation. Vous pouvez consulter ces ressources utiles sur les erreurs de conception de base de données, afin d'être averti des autres pratiques à éviter.
Tableaux fantômes
Une autre option de piste d'audit consiste à générer une table fantôme pour chaque table devant être auditée. Les tables fantômes contiennent les mêmes champs que les tables qu'ils auditent, plus les champs d'audit spécifiques (les mêmes que ceux mentionnés pour la technique de versioning de lignes).
Les tables fantômes répliquent les mêmes champs que les tables qu'ils auditent, ainsi que les champs spécifiques à des fins d'audit.
Pour générer des pistes d'audit dans des tables fantômes, l'option la plus sûre consiste à créer des déclencheurs d'insertion, de mise à jour et de suppression qui, pour chaque enregistrement affecté dans la table d'origine, génèrent un enregistrement dans la table d'audit. Les déclencheurs doivent avoir accès à toutes les informations d'audit que vous devez enregistrer dans la table fantôme. Vous devrez utiliser la fonctionnalité spécifique du moteur de base de données pour obtenir des données telles que la date et l'heure actuelles, l'utilisateur connecté, le nom de l'application et l'emplacement (adresse réseau ou nom de l'ordinateur) d'où provient l'opération.
Si l'utilisation de déclencheurs n'est pas envisageable, la logique pour générer les pistes d'audit doit faire partie de la pile applicative, dans une couche idéalement située juste avant la couche de persistance des données, afin qu'elle puisse intercepter toutes les opérations dirigées vers la base de données.
Ce type de table de journal ne doit permettre que l'insertion d'enregistrements ; s'ils permettent de modifier ou de supprimer, la piste d'audit ne remplirait plus sa fonction. Les tables doivent également utiliser des clés primaires de substitution, car les dépendances et les relations des tables d'origine ne peuvent pas leur être appliquées.
Si la table pour laquelle vous avez créé une piste d'audit possède des tables dont elle dépend, celles-ci doivent également avoir des tables fantômes correspondantes. Ceci afin que la piste d'audit ne soit pas orpheline si des modifications sont apportées aux autres tables.
Les tables fantômes sont pratiques en raison de leur simplicité et parce qu'elles n'affectent pas l'intégrité du modèle de données; les pistes d'audit restent dans des tables séparées et sont faciles à interroger. L'inconvénient est que le schéma n'est pas flexible :tout changement dans la structure de la table principale doit être reflété dans la table fantôme correspondante, ce qui rend difficile la maintenance du modèle. De plus, si la journalisation d'audit doit être appliquée à un grand nombre de tables, le nombre de tables fantômes sera également élevé, ce qui rendra la maintenance du schéma encore plus difficile.
Tables génériques pour la journalisation d'audit
Une troisième option consiste à créer des tables génériques pour les journaux d'audit. Ces tables permettent la journalisation de n'importe quelle autre table du schéma. Seules deux tables sont nécessaires pour cette technique :
Un tableau d'en-tête qui enregistre :
- La date et l'heure du changement.
- Le nom de la table.
- La clé de la ligne concernée.
- Les données utilisateur.
- Le type d'opération effectuée.
Un tableau de détails qui enregistre :
- Les noms de chaque champ concerné.
- La ou les valeurs du champ avant la modification.
- La ou les valeurs du champ après la modification. (Vous pouvez l'omettre si nécessaire, car il peut être obtenu en consultant l'enregistrement suivant dans la piste d'audit ou l'enregistrement correspondant dans le tableau audité.)
L'utilisation de tables de journaux d'audit génériques limite les types de données pouvant être auditées.
L'avantage de cette stratégie de journalisation d'audit est qu'elle ne nécessite aucune autre table que les deux mentionnées ci-dessus. De plus, les enregistrements y sont stockés uniquement pour les champs affectés par une opération. Cela signifie qu'il n'est pas nécessaire de répliquer une ligne entière d'une table lorsqu'un seul champ est modifié. De plus, cette technique vous permet de conserver un journal d'autant de tables que vous le souhaitez - sans encombrer le schéma avec un grand nombre de tables supplémentaires.
L'inconvénient est que les champs qui stockent les valeurs doivent être d'un seul type - et suffisamment large pour stocker même le plus grand des champs des tables pour lesquelles vous souhaitez générer un journal d'audit. Il est plus courant d'utiliser des champs de type VARCHAR qui acceptent un grand nombre de caractères.
Si, par exemple, vous devez générer un journal d'audit pour une table comportant un champ VARCHAR de 8 000 caractères, le champ qui stocke les valeurs dans la table d'audit doit également comporter 8 000 caractères. Cela est vrai même si vous ne stockez qu'un seul entier dans ce champ. D'autre part, si votre table contient des champs de types de données complexes, tels que des images, des données binaires, des BLOB, etc., vous devrez sérialiser leur contenu afin qu'il puisse être stocké dans les champs VARCHAR des tables de journal.
Choisissez judicieusement la conception de votre journal d'audit de base de données
Nous avons vu plusieurs alternatives pour générer la journalisation d'audit, mais aucune d'entre elles n'est vraiment optimale. Vous devez adopter une stratégie de journalisation qui n'affecte pas sensiblement les performances de votre base de données, ne la fait pas grossir de manière excessive et peut répondre à vos exigences de traçabilité. Si vous souhaitez uniquement stocker les journaux de quelques tables, les tables fantômes peuvent être l'option la plus pratique. Si vous souhaitez avoir la possibilité de consigner n'importe quelle table, les tables de journalisation génériques peuvent être préférables.
Avez-vous découvert un autre moyen de tenir un journal d'audit pour vos bases de données ? Partagez-le dans la section des commentaires ci-dessous - vos collègues concepteurs de bases de données vous en seront très reconnaissants !