Persyaratan yang cukup umum dalam aplikasi database adalah untuk melacak perubahan ke satu atau lebih entitas tertentu dalam database. Saya pernah mendengar ini disebut versi baris, tabel log atau tabel sejarah (saya yakin ada nama lain untuk itu). Ada beberapa cara untuk mendekatinya dalam RDBMS - Anda dapat menulis semua perubahan dari semua tabel sumber ke satu tabel (lebih dari satu log) atau memiliki tabel sejarah terpisah untuk setiap tabel sumber. Anda juga memiliki opsi untuk mengelola masuknya kode aplikasi atau melalui pemicu basis data.
Saya mencoba memikirkan seperti apa solusi untuk masalah yang sama akan terlihat seperti dalam database NoSQL / dokumen (khususnya MongoDB), dan bagaimana itu akan diselesaikan dengan cara yang seragam. Apakah sesederhana membuat nomor versi untuk dokumen, dan tidak pernah menimpa mereka? Membuat koleksi terpisah untuk dokumen "asli" vs. dokumen "dicatat"? Bagaimana hal ini memengaruhi permintaan dan kinerja?
Lagi pula, apakah ini skenario umum dengan database NoSQL, dan jika demikian, apakah ada solusi umum?
Jawaban:
Pertanyaan bagus, saya juga melihat ke dalam ini.
Buat versi baru pada setiap perubahan
Saya menemukan modul Versioning dari driver Mongoid untuk Ruby. Saya belum menggunakannya sendiri, tetapi dari apa yang saya temukan , itu menambahkan nomor versi ke setiap dokumen. Versi yang lebih lama tertanam dalam dokumen itu sendiri. Kelemahan utama adalah bahwa seluruh dokumen digandakan pada setiap perubahan , yang akan menghasilkan banyak konten duplikat disimpan ketika Anda berurusan dengan dokumen besar. Pendekatan ini baik-baik saja meskipun ketika Anda berurusan dengan dokumen berukuran kecil dan / atau tidak terlalu sering memperbarui dokumen.
Hanya simpan perubahan dalam versi baru
Pendekatan lain adalah dengan menyimpan hanya bidang yang diubah dalam versi baru . Kemudian Anda dapat 'meratakan' riwayat Anda untuk merekonstruksi versi dokumen apa pun. Ini agak rumit, karena Anda perlu melacak perubahan dalam model Anda dan menyimpan pembaruan dan menghapus dengan cara aplikasi Anda dapat merekonstruksi dokumen terbaru. Ini mungkin rumit, karena Anda berurusan dengan dokumen terstruktur daripada tabel SQL datar.
Simpan perubahan di dalam dokumen
Setiap bidang juga dapat memiliki riwayat individu. Rekonstruksi dokumen ke versi yang diberikan jauh lebih mudah dengan cara ini. Di aplikasi Anda, Anda tidak perlu melacak perubahan secara eksplisit, tetapi cukup buat versi baru dari properti saat Anda mengubah nilainya. Sebuah dokumen dapat terlihat seperti ini:
Menandai bagian dari dokumen sebagai dihapus dalam versi masih agak canggung. Anda bisa memperkenalkan
state
bidang untuk bagian-bagian yang dapat dihapus / dipulihkan dari aplikasi Anda:Dengan masing-masing pendekatan ini, Anda dapat menyimpan versi terbaru dan rata dalam satu koleksi dan data riwayat dalam koleksi terpisah. Ini akan meningkatkan waktu kueri jika Anda hanya tertarik pada versi terbaru dokumen. Tetapi ketika Anda membutuhkan versi terbaru dan data historis, Anda harus melakukan dua pertanyaan, bukan satu. Jadi pilihan untuk menggunakan satu koleksi vs. dua koleksi terpisah harus bergantung pada seberapa sering aplikasi Anda membutuhkan versi historis .
Sebagian besar dari jawaban ini hanyalah tumpukan pikiran saya, saya belum benar-benar mencoba semua ini. Melihat ke belakang, opsi pertama mungkin adalah solusi termudah dan terbaik, kecuali jika overhead data duplikat sangat signifikan untuk aplikasi Anda. Pilihan kedua cukup kompleks dan mungkin tidak sepadan dengan usaha. Opsi ketiga pada dasarnya adalah optimalisasi opsi dua dan harus lebih mudah diimplementasikan, tetapi mungkin tidak sepadan dengan upaya implementasi kecuali Anda benar-benar tidak bisa menggunakan opsi satu.
Menantikan umpan balik tentang ini, dan solusi orang lain untuk masalah ini :)
sumber
Kami telah mengimplementasikan sebagian ini di situs kami dan kami menggunakan 'Revisi Store dalam dokumen terpisah "(dan database terpisah). Kami menulis fungsi khusus untuk mengembalikan diff dan kami menyimpannya. Tidak terlalu sulit dan dapat memungkinkan pemulihan otomatis.
sumber
Mengapa tidak ada variasi pada perubahan Toko dalam dokumen ?
Alih-alih menyimpan versi terhadap setiap pasangan kunci, pasangan kunci saat ini dalam dokumen selalu mewakili keadaan terbaru dan 'log' perubahan disimpan dalam array sejarah. Hanya kunci-kunci yang telah berubah sejak pembuatan akan memiliki entri di log.
sumber
Seseorang dapat memiliki database NoSQL saat ini dan database NoSQL historis. Akan ada ETL malam berjalan setiap hari. ETL ini akan merekam setiap nilai dengan cap waktu, jadi alih-alih nilai itu akan selalu tupel (bidang berversi). Itu hanya akan mencatat nilai baru jika ada perubahan yang dibuat pada nilai saat ini, menghemat ruang dalam proses. Sebagai contoh, file json database NoSQL database historis ini dapat terlihat seperti ini:
sumber
Untuk pengguna Python (python 3+, dan tentu saja), ada HistoricalCollection yang merupakan perpanjangan dari objek Koleksi pymongo.
Contoh dari dokumen:
Pengungkapan penuh, saya adalah pembuat paket. :)
sumber