Podczas gdy @WW. odpowiedź jest dobrą odpowiedzią innym sposobem jest utworzenie kolumny wersji i trzymanie wszystkich wersji w tej samej tabeli.
Przy jednym stoliku podejdź do Ciebie:
- Użyj flagi, aby wskazać najnowszy ala Word Press
- LUB zrób paskudną wersję większą niż
outer join.
Przykładowy kod SQL outer joinmetody używającej numerów wersji to:
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.
Zła wiadomość jest taka, że powyższe wymaga, outer joina łączenia zewnętrzne mogą być powolne. Dobra wiadomość jest taka, że tworzenie nowych wpisów jest teoretycznie tańsze, ponieważ można to zrobić w jednej operacji zapisu bez transakcji (zakładając, że baza danych jest atomowa).
Przykładem tworzenia nowej wersji dla '/stuff'może być:
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}
)
Wstawiamy przy użyciu starych danych. Jest to szczególnie przydatne, jeśli chcesz zaktualizować tylko jedną kolumnę i uniknąć optymistycznego blokowania i / lub transakcji.
Podejście z flagami i podejście do tabeli historii wymagają wstawienia / aktualizacji dwóch wierszy.
Inną zaletą outer joinpodejścia opartego na numerach wersji jest to, że zawsze możesz później zmienić podejście do podejścia z wieloma tabelami z wyzwalaczami, ponieważ wyzwalacz powinien zasadniczo wykonywać coś podobnego do powyższego.