Шаблони для версії реляційних даних у базі даних MySQL?


12

Я намагаюся знайти підхід для проекту, де користувач може редагувати записи та мати можливість бачити минулі версії цих записів. Ось спрощена прикладна схема із використанням списку:

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
);

Таким чином, користувач може зайти і внести кілька змін до списку (тобто додати або видалити завдання, переупорядкувати завдання, позначити деякі завершені, перейменувати деякі тощо), а потім зберегти їх. На цьому етапі я хотів би створити "версію 2" списку та завдань, щоб вони мали можливість переглядати попередні версії, але коли вони отримують доступ до списку, завжди отримують останню версію.

Чи існує загальний підхід / схема дизайну для обробки даних версій таким чином у базі даних MySQL?


Зауважте, що це бібліотеки для цього. Наприклад, якщо ви використовуєте сплячий режим, є Hibernate Envers. Тож якщо у вас є якийсь фреймворк DAO для вас, спробуйте пошукати, чи є щось подібне.
Вальфрат

Відповіді:


9

Її досить часто хотіти робити це в db. Хоча ви накладаєте на нього поворот, у тому, що хочете відстежити перегляд списку елементів.

Одним із способів зробити це може бути зміна такої структури, як

Alter table lists add revision_id integer;
Alter table list_tasks add revision_id integer;

Create Table revisions
{
   id int autoincrement... (revision id)
   list_id int...
   revdate datetime...
}

Коли користувач зберігає свій список, створіть нову редакцію в revisionsтаблиці вище та призначте це значення елементам списку в, list_tasksа потім ідентифікатору ревізії в, listsщоб позначити цей ідентифікатор як "поточний". Коли користувач редагує елементи, не редагуйте наявні елементи - скоріше вставляйте нові з новим ідентифікатором версії та оновлюйте listтаблицю цією редакцією, щоб позначити її як поточну.

Потім, щоб перелічити поточні елементи, перерахуйте елементи з поточного ідентифікатора версії, зазначеного в listsтаблиці. Щоб переглянути попередні версії, ви можете отримати список попередніх версій списків із таблиці ревізій, а потім перерахувати окремі елементи на основі цього ідентифікатора.


5

Для цього рішення використовується окрема таблиця аудиту. У нього є плюси і мінуси. Ви можете скористатися видаленням старих записів із головної таблиці. Поліпшення продуктивності може бути незначним.

Додайте наступні поля до кожної аудированої таблиці:

AddUserID      int <whatever your system uses>
AddDateTime    datetime
UpdateUserID   int <whatever your system uses>
UpdateDateTime datetime
CurrentVersion int
IsDeleted      bit

Ці поля вам потрібно буде оновлювати щоразу при зміні даних. CurrentVersion збільшується на 1 (Це може використовуватися як спосіб блокування запису, але це інше питання.) IsDeleted забезпечує "м'яке видалення", щоб на нього можна було посилатися в майбутньому.

Окремі таблиці аудиту Кожна таблиця повинна мати відповідну версію таблиці _Archive або _History. Їх, мабуть, не потрібно індексувати однаково. Очевидно, що єдине поле первинного ключа не застосовуватиметься. Ви повинні мати змогу зробити складений ключ із поля ідентифікатора та UpdateDateTime.

Використання тригера (Це стосується змін, внесених всередину або поза кодом. Ви можете вирішити, чи це працює для вашої ситуації.) Або іншого кодування, коли запис додається, оновлюється або видаляється, копія запису поміщається в архів / таблиця історії. Усі версії та інші аудиторські поля підтримуються. Це скаже вам, що користувачі робили, коли коли. Таблицю можна порівняти з собою, щоб побачити, коли змінили запис або побачити тенденції.

Я добре бачив цю роботу за останні кілька років. Я хотів би почути про недоліки, які, можливо, не розглядаю.


Я підтримую це, як і GrandMasterB, і те, і інше добре, і який саме використовувати, залежить від більш детальної інформації про конкретні потреби.
нар.

-2

Я б запропонував вам прочитати цю досить детальну статтю.

https://blog.jondh.me.uk/2011/11/relational-database-versioning-strategies/comment-page-1/#comment-373850

Іншим підходом є наявність у таблиці стовпця version_id та прапор "current", який визначає, який рядок є поточним. Кожного разу, коли вам потрібно оновлення, ви можете вставити новий рядок і встановити прапор "поточного" існуючої версії на 0 / false, а щойно доданий рядок - на 1.

Таким чином, ви можете створити подання, у якому відображатимуться лише особи з поточним встановленим прапором.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.