Comment évitez-vous d'ajouter des champs d'horodatage à vos tables? [fermé]

StackOverflow https://stackoverflow.com/questions/154964

  •  03-07-2019
  •  | 
  •  

Question

J'ai une question concernant les deux colonnes supplémentaires (timeCreated, timeLastUpdated) de chaque enregistrement figurant dans de nombreuses solutions. Ma question: existe-t-il une meilleure alternative?

Scénario: vous avez une énorme base de données (en termes de tables, pas d'enregistrements), puis le client arrive et vous demande d'ajouter "& # 160;" horodatage " à 80% de vos tables.

Je pense que cela peut être accompli en utilisant un tableau séparé (TIMESTAMPS). Cette table aurait, en plus de la colonne d'horodatage évidente, le nom de la table et la clé primaire de la table en cours de mise à jour. (Je suppose ici que vous utilisez un int comme clé primaire pour la plupart de vos tables, mais que le nom de la table devra probablement être une chaîne).

Pour imaginer cela, supposons ce scénario de base. Nous aurions deux tables:

PAIEMENT: - (vos enregistrements habituels)
TIMESTAMP: - {horodatage en cours} + { TABLE_UPDATED , id_of_entry_updated , type d'horodatage }

Notez que dans cette conception, vous n'avez pas besoin de ces deux "extra". les colonnes de votre objet de paiement natif (qui, en passant, pourraient passer par votre solution ORM) car vous indexez maintenant avec TABLE_UPDATED et id_of_entry_updated . En outre, type_horodatage vous indiquera si l'entrée est destinée à l'insertion (par exemple, "1"), à la mise à jour (par exemple, "2") et à tout ce que vous voudrez peut-être ajouter, comme "suppression". ;.

J'aimerais savoir ce que vous pensez de ce design. Je suis plus intéressé par les meilleures pratiques, ce qui fonctionne et évolue dans le temps. Les références, les liens, les entrées de blog sont plus que bienvenus. Je connais au moins un brevet (en instance) qui tente de résoudre ce problème, mais il semble que les détails ne soient pas publics pour le moment.

Salut, Eduardo

Était-ce utile?

La solution

Pendant que vous y êtes, notez également l’utilisateur qui a effectué le changement.

La conception avec des tables séparées (en plus des performances de jointure mises en évidence par d’autres) est qu’elle suppose que chaque table a une colonne d’identité pour la clé. Ce n'est pas toujours vrai.

Si vous utilisez SQL Server, la nouvelle version 2008 prend en charge quelque chose qu'ils appellent Changer la capture de données qui devrait vous éviter beaucoup de peine. Je pense qu’Oracle pourrait avoir quelque chose de similaire aussi.

Mise à jour: Apparemment, Oracle l'appelle la même chose que SQL Server. Ou plutôt, SQL Server l'appelle la même chose que Oracle, puisque sa mise en œuvre est arrivée en premier;)
http://www.oracle.com/technology/oramag/ oracle / 03-nov / o63tech_bi.html

Autres conseils

J'ai utilisé un modèle dans lequel chaque table à auditer avait deux tables:

create table NAME (
  name_id int,
  first_name varchar
  last_name varchar
  -- any other table/column constraints
)

create table NAME_AUDIT (
  name_audit_id int
  name_id int
  first_name varchar
  last_name varchar
  update_type char(1) -- 'U', 'D', 'C'
  update_date datetime
  -- no table constraints really, outside of name_audit_id as PK
)

Un déclencheur de base de données est créé et renseigne NAME_AUDIT chaque fois que quelque chose est fait dans NAME . De cette façon, vous avez un enregistrement de chaque modification apportée à la table et à quel moment. L’application n’a pas vraiment connaissance de cela, car elle est maintenue par un déclencheur de base de données.

Cela fonctionne raisonnablement bien et ne nécessite aucune modification du code de l'application à mettre en œuvre.

Je pense que je préfère ajouter les horodatages aux tables individuelles. La jonction sur votre table d’horodatage sur une clé composite - l’une d’elles étant une chaîne de caractères - va être plus lente et si vous avez une grande quantité de données, cela finira par poser un réel problème.

De plus, souvent, lorsque vous examinez les horodatages, c’est lorsque vous déboguez un problème dans votre application et que vous souhaitez disposer des données à cet endroit, plutôt que de devoir toujours rejoindre la table voisine.

L’avantage de la méthode que vous proposez est qu’elle vous donne la possibilité d’ajouter d’autres champs à votre table TIMESTAMP, comme le suivi de l’utilisateur qui a effectué la modification. Vous pouvez également suivre les modifications apportées aux champs sensibles, par exemple, qui a refacturé le contrat?

La journalisation des modifications d’un enregistrement dans un fichier distinct signifie que vous pouvez afficher plusieurs modifications d’un enregistrement, telles que:

mm / jj / aa hh: mm: ss Ajouté par XXX mm / jj / aa hh: mm: ss Champ PRIX modifié par XXX, mm / jj / aa hh: mm: ss Enregistrement supprimé par XXX

Un inconvénient est le code supplémentaire que l'insertion va effectuer dans votre table TIMESTAMPS afin de refléter les modifications apportées à vos tables principales.

Si vous configurez l'horodatage pour qu'il s'exécute à partir de déclencheurs, toute action pouvant déclencher un déclencheur (Reads?) peut être enregistrée. En outre, il pourrait y avoir des avantages verrouillables.

(Prenez tout cela avec un grain de sel, je ne suis pas un gourou DBA ou SQL)

Oui, j'aime ce design et je l’utilise avec certains systèmes. Habituellement, certaines variantes de:

LogID  int
Action varchar(1)     -- ADDED (A)/UPDATED (U)/DELETED (D)
UserID varchar(20)    -- UserID of culprit :)
Timestamp datetime    -- Date/Time
TableName varchar(50) -- Table Name or Stored Procedure ran
UniqueID int          -- Unique ID of record acted upon
Notes varchar(1000)   -- Other notes Stored Procedure or Application may provide

Un cauchemar avec votre conception est que chaque insertion, mise à jour ou suppression doit atteindre cette table. Cela peut entraîner d'importants problèmes de performances et de verrouillage. C'est une mauvaise idée de généraliser un tableau comme celui-ci (pas seulement pour les horodatages). Ce serait également un cauchemar de récupérer les données.

Si, au niveau de l'interface graphique, votre code ne permet pas d'ajouter des champs que l'utilisateur ne souhaite pas voir, vous ne l'écrivez pas correctement dans votre interface graphique. Celui-ci doit spécifier uniquement le nombre minimum de colonnes dont vous avez besoin et ne sélectionnez jamais *.

Je pense que les jointures supplémentaires que vous devrez exécuter pour obtenir les horodatages seront un léger impact sur la performance et une douleur au cou. Sinon, je ne vois pas de problème.

Nous avons fait exactement ce que vous avez fait. C'est excellent pour le modèle objet et la possibilité d'ajouter de nouveaux tampons et différents types de tampons à notre modèle avec un code minimal. Nous suivions également l'utilisateur qui avait effectué le changement, et notre logique reposait en grande partie sur ces timbres. Cela s’est très bien passé.

L'un des inconvénients est de signaler et / ou d'afficher beaucoup de timbres différents à l'écran. Si vous le faites comme nous l’avons fait, cela a causé beaucoup de jointures. En outre, les changements de fin de dos étaient une douleur.

Notre solution consiste à gérer une "Transaction". table, en plus de notre " session " table. Les instructions UPDATE, INSERT et DELETE sont toutes gérées par un "Transaction". objet et chacune de ces instructions SQL est stockée dans le dossier "Transaction". table une fois qu'il a été exécuté avec succès sur la base de données. Cette " Transaction " La table a d'autres champs tels que transactiontType (I pour INSERT, D pour DELETE, U pour UPDATE), transactionDateTime, etc., et une clé étrangère "sessionId", nous indiquant finalement qui a envoyé l'instruction. Il est même possible, par un code, d’identifier qui a fait quoi et quand (Gus a créé le disque lundi, Tim a changé le prix unitaire le mardi, Liz a ajouté une réduction supplémentaire le jeudi, etc.).

Les avantages de cette solution sont les suivants:

  1. vous êtes en mesure de dire "qui et quand" et de le montrer à vos utilisateurs! (vous aurez besoin de code pour analyser les instructions SQL)
  2. si vos données sont répliquées et que la réplication échoue, vous pouvez reconstruire votre base de données via cette table

Les inconvénients sont

  1. 100 000 mises à jour de données par mois signifient 100 000 enregistrements dans Tbl_Transaction
  2. Enfin, cette table représente généralement 99% du volume de votre base de données

Notre choix: tous les enregistrements de plus de 90 jours sont automatiquement supprimés chaque matin

Philippe,

Ne supprimez pas simplement ceux de plus de 90 jours, déplacez-les d'abord vers une base de données distincte ou écrivez-les dans un fichier texte, faites quelque chose pour les conserver, mais déplacez-les simplement hors de la base de données principale de production.

Si jamais cela se résume à cela, le plus souvent, c’est "il est le plus documenté qui gagne"!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top