Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Simpan semua perubahan data dengan setiap detail (seperti Stackoverflow)

Saya sudah memikirkannya untuk sementara waktu sekarang dan hanya bisa memikirkan dua cara untuk melakukan ini. Keduanya dapat bekerja sepenuhnya transparan saat dibuat menjadi lapisan/model data abstrak.

Omong-omong, ada implementasi untuk data tabel "versibel" dalam doktrin mapper ORM. Lihat contoh di dokumen mereka . Mungkin itu sesuai dengan kebutuhan Anda, tetapi tidak sesuai dengan kebutuhan saya. Tampaknya menghapus semua data riwayat ketika catatan asli dihapus, membuatnya tidak benar-benar aman untuk direvisi.

Opsi A:memiliki salinan setiap tabel untuk menyimpan data revisi

Katakanlah Anda memiliki tabel kontak sederhana:

CREATE TABLE contact (
    id INT NOT NULL auto_increment,
    name VARCHAR(255),
    firstname VARCHAR(255),
    lastname VARCHAR(255),
    PRIMARY KEY (id)
)

Anda akan membuat salinan tabel itu dan menambahkan data revisi:

CREATE TABLE contact_revisions (
    id INT NOT NULL,
    name VARCHAR(255),
    firstname VARCHAR(255),
    lastname VARCHAR(255),
    revision_id INT auto_increment,
    type ENUM('INSERT', 'UPDATE', 'DELETE') NOT NULL,
    change_time DEFAULT current_timestamp,
    PRIMARY KEY(revision_id)
)

Lacak INSERT dan UPDATE menggunakan AFTER pemicu. Pada setiap revisi data baru pada aslinya, sisipkan salinan data baru pada tabel revisi dan atur type modifikasi dengan benar.

Untuk mencatat DELETE aman untuk direvisi, Anda juga harus memasukkan baris baru di tabel riwayat! Untuk ini, Anda harus menggunakan BEFORE DELETE memicu dan menyimpan nilai terbaru sebelum dihapus. Jika tidak, Anda harus menghapus setiap NOT NULL kendala di tabel riwayat juga.

Beberapa catatan penting terkait implementasi ini

  • Untuk tabel histori, Anda harus menghapus setiap UNIQUE KEY (di sini:PRIMARY KEY ) dari tabel revisi karena Anda akan memiliki kunci yang sama beberapa kali untuk setiap revisi data.
  • Bila Anda ALTER skema dan data di tabel asli melalui pembaruan (misalnya pembaruan perangkat lunak), Anda harus memastikan data atau koreksi skema yang sama diterapkan ke tabel riwayat dan datanya juga. Jika tidak, Anda akan mengalami masalah saat kembali ke revisi kumpulan rekor yang lebih lama.
  • Dalam implementasi dunia nyata, Anda ingin mengetahui pengguna mana yang mengubah data. Agar aman secara revisi, catatan pengguna tidak boleh dihapus dari tabel pengguna. Anda hanya perlu menonaktifkan akun dengan bendera.
  • Biasanya, satu tindakan pengguna melibatkan lebih dari satu tabel. Dalam implementasi dunia nyata, Anda juga harus melacak perubahan mana dalam beberapa tabel yang termasuk dalam satu transaksi pengguna dan juga dalam urutan yang mana. Dalam kasus penggunaan nyata, Anda ingin mengembalikan semua perubahan dari satu transaksi bersama-sama, dalam urutan terbalik. Itu akan membutuhkan tabel revisi tambahan yang melacak pengguna dan transaksi dan memiliki hubungan yang longgar dengan semua revisi individu dalam tabel riwayat.

Manfaat:

  • sepenuhnya dalam database, independen dari kode aplikasi. (yah, bukan saat melacak transaksi pengguna itu penting. itu akan memerlukan beberapa logika di luar cakupan kueri tunggal)
  • semua data dalam format aslinya, tidak ada konversi tipe implisit.
  • kinerja bagus pada penelusuran di revisi
  • kembalikan dengan mudah. Cukup lakukan INSERT .. ON DUPLICATE KEY UPDATE .. pernyataan pada tabel asli, menggunakan data dari revisi yang ingin Anda putar kembali.

Kelebihan:

  • Sulit untuk diterapkan secara manual.
  • Sulit (tetapi bukan tidak mungkin) untuk diotomatisasi dalam hal migrasi basis data/pembaruan aplikasi.

Seperti yang telah dinyatakan di atas, doktrin versionable melakukan sesuatu yang serupa.

Opsi B:memiliki tabel log perubahan pusat

kata pengantar:praktik buruk, ditampilkan sebagai ilustrasi alternatif saja.

Pendekatan ini sangat bergantung pada logika aplikasi, yang seharusnya disembunyikan dalam lapisan/model data.

Anda memiliki tabel riwayat pusat yang melacak

  • Siapa yang melakukannya
  • kapan
  • mengubah, menyisipkan, atau menghapus
  • data apa
  • di bidang mana
  • meja yang mana

Seperti pada pendekatan lain, Anda mungkin juga ingin melacak perubahan data individual mana yang termasuk dalam tindakan/transaksi pengguna tunggal dan dalam urutan yang mana.

Manfaat:

  • tidak perlu tetap sinkron dengan tabel asli saat menambahkan bidang ke tabel atau membuat tabel baru. skalanya transparan.

Kelebihan:

  • praktik buruk menggunakan nilai sederhana =penyimpanan kunci di database
  • kinerja penelusuran buruk, karena konversi tipe implisit
  • dapat memperlambat kinerja aplikasi/database secara keseluruhan, ketika tabel histori pusat menjadi hambatan karena kunci penulisan (ini hanya berlaku untuk mesin tertentu dengan kunci tabel, mis. MyISAM)
  • Jauh lebih sulit untuk menerapkan rollback
  • kemungkinan kesalahan konversi data / kehilangan presisi karena konversi tipe implisit
  • tidak melacak perubahan ketika Anda langsung mengakses database di suatu tempat dalam kode Anda alih-alih menggunakan model/lapisan data Anda dan lupa bahwa dalam hal ini Anda harus menulis ke log revisi secara manual. Mungkin menjadi masalah besar saat bekerja dalam tim dengan programmer lain.

Kesimpulan:

  • Opsi B bisa sangat berguna untuk aplikasi kecil sebagai "masuk" sederhana ketika itu hanya untuk mencatat perubahan.
  • Jika Anda ingin kembali ke masa lalu dan dapat dengan mudah membandingkan perbedaan antara revisi bersejarah 123 untuk merevisi 125 dan/atau kembali ke data lama, lalu Opsi A adalah cara yang sulit untuk dilalui.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara Menampilkan baris sebagai Kolom di MySQL?

  2. MySQL menghapus catatan duplikat tetapi tetap terbaru

  3. Buang file sql ke ClearDB di Heroku

  4. MySQL mendengarkan, beri tahu, setara

  5. WooCommerce:Menemukan produk di database