Apa yang sebenarnya ingin Anda versi? Skema atau data?
tdammers
1
Saya ingin versi datanya. Untuk tetap pada contoh cms, katakanlah versi artikel .
matcauthon
Anda mungkin ingin melihat ke Datomic.
dan_waterworth
Jawaban:
19
Pada dasarnya ada dua pendekatan: tabel audit, dengan semua nilai sebelumnya disimpan di dalamnya, atau sertakan tanggal mulai / berakhir sebagai bagian dari tabel, dan semua pembaruan membuat catatan baru sambil menutup yang lama.
Jadi pendekatan pertama mungkin lebih terukur. Karena data "yang diarsipkan" akan jarang diakses, desain basis data dapat dioptimalkan. Dan meja kerjanya tetap kecil. Tergantung pada kerumitannya, seharusnya hanya mungkin untuk menyimpan perbedaan. Apakah disarankan untuk menggunakan pola kenang - kenangan ?
matcauthon
1
Itu akan tergantung pada penggunaan Anda, mungkin cukup menggunakan pemicu untuk mengisi tabel / s dan kemudian menyediakan cara memilih apa dan seberapa jauh untuk mengembalikan.
jmoreno
Anda memiliki kesalahan ketik dalam jawaban Anda (pola pola seharusnya)
geocodezip
7
Satu ide adalah menggunakan "Masukkan-Hanya Basis Data". Ide dasarnya adalah bahwa Anda tidak pernah menghapus atau memperbarui data pada satu baris .
Setiap tabel yang harus dilacak akan memiliki dua datetimekolom fromdan to. Mereka mulai dengan nilai NULLdi masing-masing (awal waktu hingga akhir waktu). Ketika Anda perlu "mengubah" baris Anda menambahkan baris baru, dan pada saat yang sama Anda memperbarui todi baris sebelumnya ke Nowdan fromdi baris yang Anda tambahkan Now.
Sayangnya pertanyaan itu tampaknya telah dihapus :(
Douglas Gaskell
Tidak masalah, ini tautannya . Saran desain bagus lainnya dalam tautan
Yusubov
2
Saya pikir Anda dapat menggunakan pemicu untuk setiap tabel dan mempertahankan data dalam _history (atau Anda dapat memberikan nama apa pun) dan pada setiap sisipan, perbarui, hapus pada tabel utama akan memicu pemicu Anda dan Anda dapat menyimpan detailnya di tabel ini. Mekanisme pemicu juga tersedia dengan database SQLite jika Anda menggunakannya.
Mekanisme ini berguna untuk proyek-proyek besar juga. Dalam tabel ini Anda bisa mencatat informasi pengguna yang telah membuat perubahan bersama dengan cap waktu perubahan. Anda kemudian dapat mengembalikan tabel ke pencocokan cap waktu dengan kebutuhan Anda.
Setiap Database memiliki cara sendiri untuk menulis dan memicu kode. Jika Anda menggunakan SQLite, kunjungi SQLite.org untuk sintaksisnya. Untuk basis data lain, Anda dapat mengunjungi situs resminya.
Anda mungkin mengetahui mesin Sqlite db. Seluruh db disimpan dalam satu file. Api juga mendukung sistem file virtual sehingga pada dasarnya Anda dapat mengatur penyimpanan di mana saja dan dengan format apa pun, cukup menanggapi operasi baca dan tulis pada offset file tertentu. Kemungkinan aplikasi untuk ini bisa berupa enkripsi, kompresi, dan sebagainya. Bagian terbaiknya adalah layer container seharusnya tidak tahu apa-apa tentang basis data, format file sql atau sqlite, cukup patuhi callback xRead dan xWrite.
Salah satu idenya adalah menerapkan fitur mesin waktu. Jadi setiap operasi xWrite menyimpan setiap segmen yang akan ditimpa dalam "undo" history dan pengguna dapat memilih tanggal di masa lalu untuk melihat apa yang terkandung dalam db (mungkin mode read-only). Saya belum memiliki contoh kerja (ada diskusi tentang hal itu di milis sqlite), tetapi mungkin mesin lain menyediakan API VFS sehingga hal serupa mungkin terjadi. Dan begitu itu diterapkan, itu harus kompatibel dengan struktur database dari kompleksitas apa pun.
Menurut Anda, apakah pendekatan ini dapat diskalakan untuk proyek yang lebih besar?
matcauthon
Saya pikir ini bisa menambah overhead data besar untuk perubahan data besar (jelas karena setiap perubahan harus disimpan, meskipun kompresi untuk versi yang lebih lama dapat membantu). Terlepas dari itu dari sudut Anda skema Anda, selama itu berfungsi untuk dua tabel, itu berfungsi untuk dua puluh.
Maksee
1
Metode yang kami gunakan untuk memvariasikan entri basis data adalah dengan menggunakan tabel audit. Tabel memiliki skema di sepanjang garis:
Seq - Int ' Unique identifier for this table
Event - Char ' Insert / Update / Delete
TblName - Char ' Table that had field value changed
FldName - Char ' Field that was changed
KeyValue - Char ' delimited list of values for fields that make up the PK of table changed
UsrId - Char ' User who made the change
OldValue - Char ' Old value (converted to character)
NewValue - Char ' New value (converted to character)
AddTs - DateTime ' When the change was made
Kami kemudian memiliki pemicu pada Sisipkan / Perbarui / Hapus tabel yang ingin kami lacak.
Pro:
Semua data dalam satu tabel
Dapat diatur untuk melacak semua bidang atau bidang tertentu dalam sebuah tabel
Mudah menampilkan versi pada setiap bidang untuk tabel
Kekurangan:
Memiliki semua informasi audit dalam satu tabel menghasilkan sejumlah besar catatan
Saya sedang melakukan versi ini sekarang. untuk setiap catatan saya memiliki Tanggal yang Dimasukkan, Tanggal yang dimodifikasi dan dan bendera boolean Rekaman Aktif. Untuk penyisipan awal, tanggal yang Dimasukkan dan Dimodifikasi disetel ke Sekarang () (Contoh ini di Access) dan bendera catatan Aktif diatur ke true. kemudian jika saya mengubah catatan itu saya menyalin semuanya ke catatan baru, mengubah bidang yang diubah pengguna, saya meninggalkan tanggal Sisipkan sama dengan yang asli dan mengubah tanggal Dimodifikasi ke Sekarang (). Saya kemudian membalik bendera Rekaman Aktif dari catatan asli ke falsedan catatan baru ke true. Saya juga memiliki bidang untuk ModifiedRecordsParentID tempat saya menyimpan identitas catatan asli.
Kemudian Jika saya perlu melakukan query, saya hanya dapat mengembalikan record di mana ActiveRecord = truedan saya hanya akan mendapatkan informasi terbaru.
Tidak perlu untuk ActiveRecordbendera. Baris MAX (*) harus selalu menjadi catatan saat ini. Mengembalikan ke versi sebelumnya cukup menyisipkan baris kata ke dalam tabel lagi.
balikkan
Saya tidak yakin bagaimana membuat karya terpilih, tetapi sekarang setelah Anda memanggil ini, saya sedang memikirkannya dan punya ide, hmmmm
Brad
Biasanya MAX (nama_kolom) memilih nilai terbesar di kolom tabel. Untuk memilih seluruh baris, sederhana select top 1 order by id descendingakan dilakukan.
balikkan
Ya, itu berfungsi untuk satu catatan tunggal tetapi meja saya adalah kumpulan catatan anak yang perlu dipilih sekaligus tetapi bisa dimodifikasi secara individual. Hanya sedikit lebih kompleks.
Jawaban:
Pada dasarnya ada dua pendekatan: tabel audit, dengan semua nilai sebelumnya disimpan di dalamnya, atau sertakan tanggal mulai / berakhir sebagai bagian dari tabel, dan semua pembaruan membuat catatan baru sambil menutup yang lama.
Pembaruan: SQL SERVER 2016 mendukung ini sebagai pola desain / jenis tabel - https://docs.microsoft.com/en-us/sql/relational-databases/tables/temporal-tables?view=sql-server-2017
sumber
Satu ide adalah menggunakan "Masukkan-Hanya Basis Data". Ide dasarnya adalah bahwa Anda tidak pernah menghapus atau memperbarui data pada satu baris .
Setiap tabel yang harus dilacak akan memiliki dua
datetime
kolomfrom
danto
. Mereka mulai dengan nilaiNULL
di masing-masing (awal waktu hingga akhir waktu). Ketika Anda perlu "mengubah" baris Anda menambahkan baris baru, dan pada saat yang sama Anda memperbaruito
di baris sebelumnya keNow
danfrom
di baris yang Anda tambahkanNow
.Untuk info lebih rinci, lihat:
Teknik ini disebut
AuditTrail
untuk mengelola data lawas, dan itu agak menyimpan sejarah perubahan.Sepertinya pertanyaan seperti ini sudah diposting:
sumber
Saya pikir Anda dapat menggunakan pemicu untuk setiap tabel dan mempertahankan data dalam _history (atau Anda dapat memberikan nama apa pun) dan pada setiap sisipan, perbarui, hapus pada tabel utama akan memicu pemicu Anda dan Anda dapat menyimpan detailnya di tabel ini. Mekanisme pemicu juga tersedia dengan database SQLite jika Anda menggunakannya.
Mekanisme ini berguna untuk proyek-proyek besar juga. Dalam tabel ini Anda bisa mencatat informasi pengguna yang telah membuat perubahan bersama dengan cap waktu perubahan. Anda kemudian dapat mengembalikan tabel ke pencocokan cap waktu dengan kebutuhan Anda.
Setiap Database memiliki cara sendiri untuk menulis dan memicu kode. Jika Anda menggunakan SQLite, kunjungi SQLite.org untuk sintaksisnya. Untuk basis data lain, Anda dapat mengunjungi situs resminya.
sumber
Anda mungkin mengetahui mesin Sqlite db. Seluruh db disimpan dalam satu file. Api juga mendukung sistem file virtual sehingga pada dasarnya Anda dapat mengatur penyimpanan di mana saja dan dengan format apa pun, cukup menanggapi operasi baca dan tulis pada offset file tertentu. Kemungkinan aplikasi untuk ini bisa berupa enkripsi, kompresi, dan sebagainya. Bagian terbaiknya adalah layer container seharusnya tidak tahu apa-apa tentang basis data, format file sql atau sqlite, cukup patuhi callback xRead dan xWrite.
Salah satu idenya adalah menerapkan fitur mesin waktu. Jadi setiap operasi xWrite menyimpan setiap segmen yang akan ditimpa dalam "undo" history dan pengguna dapat memilih tanggal di masa lalu untuk melihat apa yang terkandung dalam db (mungkin mode read-only). Saya belum memiliki contoh kerja (ada diskusi tentang hal itu di milis sqlite), tetapi mungkin mesin lain menyediakan API VFS sehingga hal serupa mungkin terjadi. Dan begitu itu diterapkan, itu harus kompatibel dengan struktur database dari kompleksitas apa pun.
sumber
Metode yang kami gunakan untuk memvariasikan entri basis data adalah dengan menggunakan tabel audit. Tabel memiliki skema di sepanjang garis:
Kami kemudian memiliki pemicu pada Sisipkan / Perbarui / Hapus tabel yang ingin kami lacak.
Pro:
Kekurangan:
sumber
Saya sedang melakukan versi ini sekarang. untuk setiap catatan saya memiliki Tanggal yang Dimasukkan, Tanggal yang dimodifikasi dan dan bendera boolean Rekaman Aktif. Untuk penyisipan awal, tanggal yang Dimasukkan dan Dimodifikasi disetel ke Sekarang () (Contoh ini di Access) dan bendera catatan Aktif diatur ke
true
. kemudian jika saya mengubah catatan itu saya menyalin semuanya ke catatan baru, mengubah bidang yang diubah pengguna, saya meninggalkan tanggal Sisipkan sama dengan yang asli dan mengubah tanggal Dimodifikasi ke Sekarang (). Saya kemudian membalik bendera Rekaman Aktif dari catatan asli kefalse
dan catatan baru ketrue
. Saya juga memiliki bidang untuk ModifiedRecordsParentID tempat saya menyimpan identitas catatan asli.Kemudian Jika saya perlu melakukan query, saya hanya dapat mengembalikan record di mana
ActiveRecord = true
dan saya hanya akan mendapatkan informasi terbaru.sumber
ActiveRecord
bendera. Baris MAX (*) harus selalu menjadi catatan saat ini. Mengembalikan ke versi sebelumnya cukup menyisipkan baris kata ke dalam tabel lagi.select top 1 order by id descending
akan dilakukan.juga, jika Anda ingin menyimpan SEMUA perubahan pada DB dari waktu ke waktu, Anda mungkin ingin memeriksa pencatatan ( /programming/3394132/where-can-i-find-the-mysql-transaction-log )
sumber