Mój wybór byłby odmianą podejścia 2. Pogrubienie wskazuje pola w kluczu podstawowym.
- Wstawiasz każdy artykuł do tabeli
articles_versioned
(identyfikator , sygnatura czasowa , imię i nazwisko, tekst) - Twoja druga tabela to
articles
(identyfikator , sygnatura czasowa, [nazwa, tekst]). Zwróć uwagę, że sygnatura czasowa nie jest podstawowa; nazwa i tekst mogą być replikowane lub możesz użyć sprzężenia zarticles_versioned
(co będzie szybkie, ponieważ id i znacznik czasu toarticles_versioned
klucz podstawowy) articles_versioned
ma wyzwalacz podczas wstawiania, który pobiera właśnie wstawiony wiersz i replikuje go warticles
- Aby przywrócić określoną wersję artykułu, modyfikuj
articles
stół.
Zaletami tego podejścia są:
- Dostajesz za darmo inne informacje (data i godzina artykułu) w swojej tabeli, które i tak możesz potrzebować
- Nie musisz wysyłać zapytań do bazy danych, aby uzyskać aktualną datę. Jeśli używasz wersji, musisz.
- Twój kod nie musi wstawiać artykułu w dwóch tabelach. Po prostu wstawiasz w
articles_versioned
i czytaj zarticles
, db zajmuje się migracją danych, gdy wstawiasz je za pomocą wyzwalacza, unikając wszelkich problemów ze spójnością.
Wady
- W środowisku o dużej współbieżności dwie wersje mogą być wstawiane w tym samym czasie, więc jedna z nich może się nie powieść. Nie powinno to stanowić problemu podczas wstawiania artykułów napisanych przez użytkowników (jest to wysoce nieprawdopodobne, biorąc pod uwagę precyzję znaczników czasu w dzisiejszych czasach). Jeśli nie określisz znacznika czasu w swoim
INSERT
oświadczenie, ale zamiast tego ustawiasz pole daty i godziny na aktualny czas jako wartość domyślną, możesz całkowicie uniknąć tego problemu.
Aby odpowiedzieć na resztę twojego pytania. Podejście 1 nie doprowadzi do dłuższych zapytań, o ile dodasz indeks stanu. Ma to sens tylko wtedy, gdy masz wiele różnych wersji każdego artykułu; tak długo, jak masz średnio 2 wersje na artykuł lub mniej, indeks tylko cię spowolni, a podejście 2 i tak nie byłoby sensownie szybsze (chociaż nadal polecam moje podejście, ponieważ upraszcza kod, ponieważ przywracanie wersji nie nie wymagają przełączania statusu dla dwóch rzędów).
Powiązane zasoby, takie jak obrazy, powinny mieć podobną wersję. Zakładam, że zapisujesz je w systemie plików; zamiast zapisywać je z prawdziwym imieniem, użyj tabeli (id , nazwa_obrazu), aby nadać każdemu obrazowi identyfikator, a następnie zapisz obraz jako -id-.jpg
. Pole image_name pozwoli Ci dowiedzieć się, jaka była oryginalna nazwa pliku (jeśli Ci na tym zależy). W ten sposób możesz wersjonować obrazy w taki sam sposób, jak wersjonujesz artykuły, a w artykułach użyjesz czegoś takiego jak <img src="-id-.jpg">
, o którym wiesz, że pozostanie dostępny na zawsze.