Próbuję znaleźć podejście do projektu, w którym użytkownik może edytować rekordy i móc zobaczyć poprzednie wersje tych rekordów. Oto uproszczony przykładowy schemat z wykorzystaniem listy:
TABLE list (
id int auto_increment primary key,
user_id int,
title varchar(255)
);
TABLE list_tasks (
id int auto_increment primary key,
list_id int,
title varchar(255),
order int,
is_complete tinyint
);
Tak więc użytkownik może wejść i dokonać kilku zmian na liście (tj. Dodać lub usunąć zadania, zmienić kolejność zadań, oznaczyć niektóre jako zakończone, zmienić nazwy niektórych itd.), A następnie zapisać je. W tym momencie chciałbym wygenerować „wersję 2” listy i zadań oraz umożliwić im przeglądanie poprzednich wersji, ale kiedy uzyskują dostęp do listy, zawsze otrzymują najnowszą wersję.
Czy istnieje wspólny wzorzec podejścia / projektowania do obsługi wersjonowania danych w ten sposób w bazie danych MySQL?
mysql
versioning
GSto
źródło
źródło
Odpowiedzi:
Często zdarza się, że chcesz to zrobić w db. Chociaż kładziesz na nim nacisk, ponieważ chcesz śledzić wersję listy przedmiotów.
Jednym ze sposobów na to może być zmiana struktury takiej jak
Gdy użytkownik zapisze swoją listę, utwórz nową wersję w
revisions
powyższej tabeli i przypisz tę wartość do elementów listy w,list_tasks
a następnie do identyfikatora zmiany w,lists
aby oznaczyć ten identyfikator jako „bieżącą” wersję. Gdy użytkownik edytuje elementy, nie edytuj istniejących elementów - zamiast tego wstaw nowe z nowym identyfikatorem wersji i zaktualizujlist
tabelę z tą wersją, aby oznaczyć ją jako bieżącą.Następnie, aby wyświetlić listę bieżących elementów, wypisz elementy z bieżącego identyfikatora zmiany określonego w
lists
tabeli. Aby przeglądać poprzednie wersje, możesz uzyskać listę poprzednich wersji list z tabeli wersji, a następnie listę poszczególnych pozycji na podstawie tego identyfikatora.źródło
To rozwiązanie wykorzystuje osobną tabelę kontroli. Ma zalety i wady. Może wolisz wyeliminować stare rekordy z głównego stołu. Poprawa wydajności może być nieznaczna.
Dodaj następujące pola do każdej kontrolowanej tabeli:
Będziesz musiał zaktualizować te pola przy każdej zmianie danych. CurrentVersion zwiększa się o 1 (może to służyć jako sposób na zablokowanie rekordu, ale to inne pytanie.) IsDeleted zapewnia „miękkie usuwanie”, aby można było do niego odwoływać w przyszłości.
Oddzielne tabele kontroli Każda tabela powinna mieć odpowiednią wersję tabeli _Archive lub _History. Te prawdopodobnie nie muszą być indeksowane w ten sam sposób. Oczywiście jedno pole klucza podstawowego nie będzie miało zastosowania. Powinieneś być w stanie zrobić klucz złożony z pola ID i UpdateDateTime.
Za pomocą wyzwalacza (odniesie się to do zmian dokonanych w kodzie lub poza nim. Możesz zdecydować, czy to zadziała w twojej sytuacji). / tabela historii. Wszystkie wersje i inne pola kontroli są utrzymywane. Dzięki temu dowiesz się, co użytkownicy zrobili, kiedy. Tabelę można porównać do siebie, aby zobaczyć, kiedy rekord został zmieniony lub zobaczyć trendy.
Widziałem tę pracę dobrze w ciągu ostatnich kilku lat. Chciałbym usłyszeć o wadach, których być może nie rozważam.
źródło
Proponuję przeczytać ten bardzo szczegółowy artykuł.
https://blog.jondh.me.uk/2011/11/relational-database-versioning-strategies/comment-page-1/#comment-373850
Innym podejściem jest posiadanie kolumny version_id w tabeli i flagi „bieżącej”, która określa, który wiersz jest bieżącym. Za każdym razem, gdy potrzebujesz aktualizacji, możesz wstawić nowy wiersz i ustawić flagę „bieżąca” istniejącej wersji na 0 / false, a nowo dodany wiersz na 1.
W ten sposób możesz utworzyć widok pokazujący tylko te z bieżącym zestawem flag.
źródło