Pola untuk Versi Data Relasional dalam database MySQL?

12

Saya mencoba menemukan pendekatan untuk proyek, di mana Seorang pengguna dapat mengedit catatan, dan dapat melihat versi sebelumnya dari catatan tersebut. Berikut adalah skema contoh yang disimulasikan, menggunakan daftar:

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

Jadi pengguna dapat masuk, dan melakukan beberapa pengeditan pada daftar, (yaitu, menambah atau menghapus tugas, memesan ulang tugas, tandai beberapa selesai, ganti nama beberapa, dll.), Lalu simpan. Pada titik ini, saya ingin membuat 'versi 2' dari daftar dan tugas, dan membuatnya dapat melihat versi sebelumnya, tetapi ketika mereka mengakses daftar, selalu dapatkan versi terbaru.

Apakah ada pendekatan / pola desain umum untuk menangani data versi dengan cara ini di database MySQL?

GSto
sumber
Perhatikan bahwa mereka adalah pustaka untuk ini. Misalnya jika Anda menggunakan Hibernate, ada Hibernate Envers. Jadi jika Anda memiliki kerangka kerja yang menangani DAO untuk Anda, cobalah untuk mencari jika ada sesuatu seperti ini.
Walfrat

Jawaban:

9

Sangat umum untuk ingin melakukan itu di db. Meskipun Anda memelintirnya di bahwa Anda ingin melacak revisi untuk daftar item.

Salah satu cara untuk melakukan ini mungkin dengan mengubah struktur seperti

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...
}

Ketika pengguna menyimpan daftar mereka, buat revisi baru di revisionstabel di atas dan tetapkan nilai itu ke daftar item di list_tasksdan kemudian ke id revisi listsuntuk menandai id itu sebagai revisi 'saat ini'. Ketika pengguna mengedit item, jangan mengedit item yang ada - melainkan, masukkan yang baru dengan id revisi baru dan perbarui listtabel dengan revisi itu untuk menandainya sebagai yang sekarang.

Kemudian untuk daftar item saat ini, daftar item dari id revisi saat ini yang ditentukan dalam liststabel. Untuk menelusuri versi sebelumnya, Anda bisa mendapatkan daftar revisi sebelumnya dari daftar dari tabel revisi, dan kemudian daftar masing-masing item berdasarkan id itu.

GrandmasterB
sumber
5

Solusi ini menggunakan tabel audit terpisah. Ini memiliki pro dan kontra. Anda mungkin lebih suka menghilangkan catatan lama dari tabel utama Anda. Peningkatan kinerja dapat diabaikan.

Tambahkan bidang berikut ke setiap tabel yang diaudit:

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

Anda harus memperbarui bidang ini setiap kali data berubah. CurrentVersion semakin bertambah dengan 1 (Ini bisa digunakan sebagai cara untuk mengunci catatan, tapi itu pertanyaan lain.) IsDeleted memberikan "penghapusan lunak" sehingga dapat direferensikan di masa depan.

Tabel Audit Terpisah Setiap tabel harus memiliki versi tabel _Archive atau _History yang sesuai. Ini mungkin tidak perlu diindeks dengan cara yang sama. Jelas satu bidang kunci utama tidak akan berlaku. Anda harus dapat membuat kunci komposit dari bidang ID dan UpdateDateTime.

Menggunakan pemicu (Ini akan membahas perubahan yang dibuat di dalam atau di luar kode Anda. Anda dapat memutuskan apakah ini bekerja untuk situasi Anda.) Atau pengkodean lainnya, ketika catatan ditambahkan, diperbarui atau dihapus, salinan catatan ditempatkan di arsip / tabel sejarah. Semua versi dan bidang audit lainnya dipertahankan. Ini akan memberi tahu Anda apa yang dilakukan pengguna saat kapan. Tabel dapat dibandingkan dengan dirinya sendiri untuk melihat kapan catatan diubah atau untuk melihat tren.

Saya telah melihat pekerjaan ini dengan baik selama beberapa tahun terakhir. Saya ingin mendengar tentang kekurangan yang mungkin tidak saya pertimbangkan.

JeffO
sumber
Saya memperbaiki ini dan juga GrandMasterB, keduanya bagus dan mana yang akan digunakan tergantung pada lebih detail pada kebutuhan spesifik.
Junky
-2

Saya sarankan Anda membaca artikel yang terperinci ini.

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

Pendekatan lain adalah memiliki kolom version_id di tabel Anda dan bendera 'saat ini' yang menentukan baris mana yang saat ini. Setiap kali Anda membutuhkan pembaruan, Anda dapat menyisipkan baris baru dan mengatur flag 'current' versi yang ada ke 0 / false dan baris yang baru ditambahkan ke 1.

Dengan cara ini, Anda dapat membuat tampilan yang hanya menampilkan setelan flag saat ini.

Ehsan
sumber