Base de données – Gestion des versions de données

J’ai lu quelques questions sur SO (comme celle-ci ) concernant la gestion des versions de vos données dans une firebase database.

J’ai aimé certaines des suggestions qui ont été mentionnées. J’ai eu le plus longtemps besoin de revoir un grand nombre de mes tables, mais je n’y suis jamais arrivé. En tant que programmeur avec un simple travail sur la firebase database, je me demandais comment procéder.

Je ne demande pas la solution réelle dans la syntaxe SQL. Je peux finalement comprendre cela (ou publier SO le moment venu). Je demande juste aux gens de commenter comment ils s’y prendraient et tous les problèmes de performance potentiels qui pourraient exister si je devais «réviser» des centaines de millions de disques. Ou toute autre suggestion, à condition qu’elle soit basée sur l’exemple ci-dessous.

Prenons un exemple simple:

Person ------------------------------------------------ ID UINT NOT NULL, PersonID UINT NOT NULL, Name VARCHAR(200) NOT NULL, DOB DATE NOT NULL, Email VARCHAR(100) NOT NULL Audit ------------------------------------------------ ID UINT NOT NULL, UserID UINT NOT NULL, -- Who TableName VARCHAR(50) NOT NULL, -- What OldRecID UINT NOT NULL, -- Where NewRecID UINT NOT NULL, AffectedOn DATE NOT NULL, -- When Comment VARCHAR(500) NOT NULL -- Why 

Je ne suis pas sûr de savoir comment lier le tableau d’audit à d’autres tables (telles que Person) si le TableName est une chaîne?

Aussi, en supposant que j’ai trois interfaces graphiques à remplir:

  1. Un dossier complet pour un identifiant de personne spécifique
  2. Une vue tableau répertoriant toutes les personnes (par identifiant)
  3. Une vue montrant chaque personne avec ses informations de révision sous chaque entrée (nombre de révisions par personne, dates des révisions, commentaires de révision, etc.), classés par les dernières révisions.

Pour accomplir 1 et 2, serait-il préférable d’interroger la table Person ou la table Audit?

Pour accomplir 3, un soi-disant expert en bases de données obtiendrait-il simplement tous les enregistrements et les transmettrait-il au logiciel pour traitement, ou regrouperait-il par PersonID et Affected date? Est-ce généralement traité en une ou plusieurs requêtes?

Au fil des ans, j’ai réalisé différents programmes d’audit et je vais actuellement mettre en place quelque chose comme ceci:

 Person ------------------------------------------------ ID UINT NOT NULL, PersonID UINT NOT NULL, Name VARCHAR(200) NOT NULL, DOB DATE NOT NULL, Email VARCHAR(100) NOT NULL Person_History ------------------------------------------------ ID UINT NOT NULL, PersonID UINT NOT NULL, Name VARCHAR(200) NOT NULL, DOB DATE NOT NULL, Email VARCHAR(100) NOT NULL AuditID UINT NOT NULL Audit ------------------------------------------------ ID UINT NOT NULL, UserID UINT NOT NULL, -- Who AffectedOn DATE NOT NULL, -- When Comment VARCHAR(500) NOT NULL -- Why 

Les enregistrements actuels sont toujours dans la table Person. S’il y a un changement, un enregistrement d’audit est créé et l’ancien enregistrement est copié dans la table Person_History (notez que l’ID ne change pas et qu’il peut y avoir plusieurs versions).

L’ID d’audit se trouve dans les tables * _History, ce qui vous permet de lier plusieurs modifications d’enregistrement à un enregistrement d’audit si vous le souhaitez.

MODIFIER:
Si vous ne disposez pas d’une table d’historique distincte pour chaque table de base et que vous souhaitez utiliser la même table pour stocker les enregistrements anciens et «supprimés», vous devez marquer les enregistrements avec un indicateur d’état. Le problème est que cela pose un réel problème lors de l’interrogation des enregistrements actuels – croyez-moi, j’ai fait cela.

Que diriez-vous de créer la table normalement, d’avoir une colonne ModifiedDate sur chaque enregistrement (et ModifiedBy si vous préférez), et de faire tout votre access aux données via une vue matérialisée qui regroupe les données par Id et ensuite HAVING ModifiedDate = MAX (ModifiedDate )?

De cette façon, l’ajout d’un nouvel enregistrement avec le même identifiant qu’un autre permettra de supprimer l’ancien enregistrement de la vue. Si vous souhaitez interroger l’historique, ne parcourez pas la vue

J’ai toujours trouvé que le maintien de différentes tables avec les mêmes colonnes était complexe et sujet aux erreurs.

Après le post de DJ en utilisant une table d’historique par table de base et un commentaire de Karl sur d’éventuels problèmes de performances, j’ai effectué quelques recherches SQL afin de trouver le moyen le plus rapide de transférer un enregistrement d’une table à une autre.

Je voulais juste documenter ce que j’ai trouvé:

Je pensais que je devrais faire une extraction SQL pour charger l’enregistrement à partir de la table de base, suivi d’une commande SQL pour placer l’enregistrement dans la table d’historique, suivi d’une mise à jour de la table de base pour insérer les données modifiées. Total de 3 transactions.

Mais à ma grande surprise, j’ai réalisé que vous pouviez faire les deux premières transactions en utilisant une seule instruction SQL en utilisant la syntaxe SELECT INTO. Je parie que la performance serait cent fois plus rapide en faisant cela.

Cela nous laisserait alors simplement mettre à jour l’enregistrement avec les nouvelles données dans la table de base.

Je n’ai toujours pas trouvé une déclaration SQL pour faire les 3 transactions à la fois (je doute que je le fasse).

J’aime votre table d’audit, c’est un bon début. Vous avez un problème de cardinalité avec votre table d’audit.

 Person ------------------------------------------------ ID UINT NOT NULL, PersonID UINT NOT NULL, Name VARCHAR(200) NOT NULL, DOB DATE NOT NULL, Email VARCHAR(100) NOT NULL, AuditID UINT NOT NULL Audit ------------------------------------------------ ID UINT NOT NULL, TableName VARCHAR(50) NOT NULL, -- What TableKey UINT NOT NULL, CreateDate DATETIME NOT NULL DEFAULT(NOW), CreateUserID UINT NOT NULL, ChangeDate DATETIME NOT NULL DEFAULT(NOW), ChangeUserID UINT NOT NULL Audit_Item ------------------------------------------------ ID UINT NOT NULL, AuditID UINT NOT NULL, -- Which audit record UserID UINT NOT NULL, -- Who OldRecID UINT NOT NULL, -- Where NewRecID UINT NOT NULL, AffectedOn DATE NOT NULL, -- When Comment VARCHAR(500) NOT NULL -- Why 

La mise en page initiale proposée comporte un seul enregistrement d’audit qui renvoie (je suppose) deux enregistrements de personne. Les défis de cette conception sont:

  • Quels enregistrements dans votre tableau personnel sont les “vrais” enregistrements actuels?
  • Comment représenter l’historique complet des modifications apscopes à l’enregistrement Personne? Si vous pointez vers deux enregistrements de la table Person, reportez-vous au point 1: lequel est l’enregistrement actuel?
  • Les champs Create *, Change * sont créés à partir d’une collection d’enregistrements Audit_Item. Ils ne sont là que pour faciliter l’access.
  • La clé AuditID dans la table Personne vous permet de pointer vers la table d’audit et d’accéder à l’historique de la personne individuelle sans avoir à interroger la table d’audit avec la clause WHERE TableName='Person'