Alors que @WW. La réponse est une bonne réponse, une autre manière est de créer une colonne de version et de conserver toutes vos versions dans le même tableau.
Pour une approche de table, vous pouvez soit:
- Utilisez un drapeau pour indiquer le dernier ala Word Press
- OU faire une version méchante supérieure à
outer join
.
Un exemple de SQL de la outer join
méthode utilisant des numéros de révision est:
SELECT tc.*
FROM text_content tc
LEFT OUTER JOIN text_content mc ON tc.path = mc.path
AND mc.revision > tc.revision
WHERE mc.revision is NULL
AND tc.path = '/stuff' -- path in this case is our natural id.
La mauvaise nouvelle est que ce qui précède nécessite un outer join
et les jointures externes peuvent être lentes. La bonne nouvelle est que la création de nouvelles entrées est théoriquement moins chère car vous pouvez le faire en une seule opération d'écriture sans transactions (en supposant que votre base de données soit atomique).
Un exemple de création d'une nouvelle révision pour '/stuff'
pourrait être:
INSERT INTO text_content (id, path, data, revision, revision_comment, enabled, create_time, update_time)
(
SELECT
(md5(random()::text)) -- {id}
, tc.path
, 'NEW' -- {data}
, (tc.revision + 1)
, 'UPDATE' -- {comment}
, 't' -- {enabled}
, tc.create_time
, now()
FROM text_content tc
LEFT OUTER JOIN text_content mc ON tc.path = mc.path
AND mc.revision > tc.revision
WHERE mc.revision is NULL
AND tc.path = '/stuff' -- {path}
)
Nous insérons en utilisant les anciennes données. Ceci est particulièrement utile si vous ne souhaitez mettre à jour qu'une seule colonne et éviter le verrouillage optimiste et / ou les transactions.
L'approche par indicateur et l'approche par table d'historique nécessitent l'insertion / la mise à jour de deux lignes.
L'autre avantage de l' outer join
approche du numéro de révision est que vous pouvez toujours refactoriser ultérieurement l'approche à plusieurs tables avec des déclencheurs, car votre déclencheur doit essentiellement faire quelque chose comme ci-dessus.