Dalam proyek yang sedang saya kerjakan, setiap perubahan pada baris di beberapa tabel database harus dilacak untuk audit atau rollback lebih lanjut. Pasti mudah untuk menemukan siapa yang memodifikasi baris, dari mana alamat IP dan kapan, dan dapat mengembalikan versi sebelumnya.
Hal serupa digunakan misalnya oleh Stack Exchange. Ketika saya mengubah pertanyaan orang lain, adalah mungkin untuk menemukan bahwa saya mengubahnya, dan untuk mengembalikannya.
Apa teknik umum yang digunakan untuk menyimpan setiap perubahan ke objek dalam database , mengingat skema saya saat ini sebagian besar memiliki sifat yang sama (di bawah) dengan aplikasi bisnis rata-rata?
- Objek memiliki ukuran yang relatif kecil: mungkin ada beberapa
nvarchar(1000)
contohnya, tetapi bukan gumpalan besar data biner, yang ini disimpan langsung pada disk, dan diakses secara langsung, dan tidak melalui Microsoft SQLfilestream
, - Beban basis data sangat rendah dan seluruh basis data ditangani oleh satu mesin virtual di server,
- Akses ke versi sebelumnya tidak harus secepat akses ke versi terbaru, tetapi tetap harus up-to-date¹ dan tidak terlalu lambat².
<tl-dr>
Saya memikirkan kasus-kasus berikut, tetapi saya tidak memiliki pengalaman nyata dengan skenario semacam itu, jadi saya akan mendengar pendapat orang lain:
Simpan segala sesuatu di tabel yang sama, bedakan baris dengan ID dan versi. IMO, itu benar-benar bodoh, dan akan cepat atau lambat akan terluka pada tingkat kinerja. Dengan pendekatan ini, juga tidak mungkin untuk mengatur tingkat keamanan yang berbeda untuk item terbaru dan jejak versi. Akhirnya, setiap permintaan akan lebih rumit untuk ditulis. Sebenarnya, untuk mengakses data terbaru, saya akan dipaksa untuk mengelompokkan semuanya berdasarkan ID dan mengambil, di setiap kelompok, versi terakhir.
Simpan versi terbaru dalam satu tabel, dan, pada setiap perubahan, salin versi yang sudah usang ke tabel lain dalam skema lain. Kelemahannya adalah bahwa setiap kali, kami menyimpan setiap nilai, meskipun itu tidak berubah. Menetapkan nilai yang tidak berubah ke
null
bukan solusi, karena saya juga harus melacak ketika nilai diubah kenull
atau darinull
.Simpan versi terbaru dalam satu tabel, dan daftar properti yang diubah dengan nilai sebelumnya di tabel lain. Hal ini tampaknya memiliki dua kelemahan: yang paling penting adalah bahwa satu-satunya cara untuk memilah jenis heterogen dari nilai sebelumnya dalam kolom yang sama adalah memiliki
binary(max)
. Yang kedua adalah, saya percaya, akan lebih sulit untuk menggunakan struktur seperti itu ketika menampilkan versi sebelumnya kepada pengguna.Lakukan hal yang sama seperti pada dua poin sebelumnya, tetapi simpan versi dalam database terpisah. Dari segi kinerja, mungkin menarik untuk menghindari memperlambat akses ke versi terbaru dengan memiliki versi sebelumnya di database yang sama; tetap, saya percaya bahwa ini adalah optimasi prematur dan harus dilakukan hanya jika ada bukti bahwa memiliki versi yang lebih lama dan terbaru dalam database yang sama adalah hambatan.
</tl-dr>
¹ Misalnya, akan tidak dapat diterima untuk menyimpan perubahan ke dalam file log, seperti yang dilakukan untuk log HTTP, dan menyiram data dari log ke database pada malam hari ketika beban server paling rendah. Informasi tentang berbagai versi harus segera tersedia atau segera; penundaan beberapa detik dapat diterima.
² Informasi tidak sering diakses dan hanya oleh kelompok pengguna tertentu, tetapi tetap saja, tidak dapat diterima untuk memaksa mereka menunggu selama 30 detik agar daftar versi ditampilkan. Sekali lagi, penundaan beberapa detik dapat diterima.