Desain terbaik untuk tabel database changelog / audit? [Tutup]


114

Saya perlu membuat tabel database untuk menyimpan log perubahan / audit yang berbeda (ketika ada sesuatu yang ditambahkan, dihapus, dimodifikasi, dll). Saya tidak perlu menyimpan info yang sangat rinci, jadi saya memikirkan sesuatu seperti:

  • id (untuk acara)
  • pengguna yang memicunya
  • nama acara
  • Deskripsi acara
  • stempel waktu acara

Apakah saya melewatkan sesuatu di sini? Jelas saya dapat terus meningkatkan desain, meskipun saya tidak berencana untuk membuatnya rumit (membuat tabel lain untuk jenis acara atau hal-hal seperti itu tidak mungkin dilakukan karena ini merupakan komplikasi untuk kebutuhan saya).


Saya membaca jawaban Anda dan saya terkejut tidak ada yang berbicara tentang Law. Saya tahu bahwa beberapa hukum atau dokumen praktik yang baik menjelaskan bagaimana kita HARUS menerapkan tabel audit (hanya baca). Tetapi saya tidak memiliki informasi lebih dari ini. Saya hanya tahu bahwa itu ada. Saya berpikir tentang jejak Audit di CFR 21 bagian 11.
Bastien Vandamme

Jawaban:


70

Dalam proyek yang saya kerjakan, log audit juga dimulai dari desain yang sangat minimalis, seperti yang Anda jelaskan:

event ID
event date/time
event type
user ID
description

Idenya sama: untuk membuat segalanya tetap sederhana.

Namun, dengan cepat menjadi jelas bahwa desain minimalis ini tidak cukup. Audit tipikal bermuara pada pertanyaan-pertanyaan seperti ini:

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

Jadi, untuk dapat menjawab pertanyaan semacam itu dengan cepat (menggunakan SQL), kami akhirnya memiliki dua kolom tambahan di tabel audit.

object type (or table name)
object ID

Saat itulah desain log audit kami benar-benar stabil (untuk beberapa tahun sekarang).

Tentu saja, "perbaikan" terakhir hanya akan bekerja untuk tabel yang memiliki kunci pengganti. Tapi coba tebak? Semua tabel kami yang layak diaudit memang memiliki kunci seperti itu!


Satu-satunya masalah yang saya hadapi dengan desain ini (jejak audit berbasis 'deskripsi') adalah dengan melokalkan bahasa yang digunakan di bidang itu.
Sam Wilson

@ Sam Saya tidak melihat masalah seperti itu, jika pesan dihasilkan oleh sistem, cukup gunakan kunci di sini untuk string terjemahan;
JCM

4
@Hiru: Ketika Anda "menggabungkan" dua atau lebih konsep yang berbeda ke dalam satu kolom, lebih sering daripada tidak itu akan menjadi bumerang, cepat atau lambat. Misalnya, jika Anda "menggabungkan" jenis peristiwa dan jenis objek, hal itu akan memengaruhi kueri seperti "tunjukkan rekaman untuk semua objek dari jenis yang diberikan" dan "tunjukkan rekaman untuk semua peristiwa dari jenis tertentu" (kueri akan lebih banyak rumit dan kemungkinan besar akan bekerja lebih lambat).
Yarik

3
Selain kolom ini, seseorang dapat memiliki kolom tambahan untuk deskripsi terstruktur / payload peristiwa terstruktur . Kolom ini akan menampung detail acara (dengan kerumitan apa pun) dalam format yang dapat dibaca komputer, XML / JSON. Mudah untuk membuat serial, untuk mengajukan kueri (setidaknya di Postgres / MSSQL), untuk dipikirkan.
turdus-merula

1
@Benjamin: Jawabannya ada di model domain (alias model bisnis). Jika model memungkinkan pembuatan entitas secara bersamaan (misalnya sebagai bagian dari transaksi logis) maka saya tidak melihat ada masalah dalam memiliki banyak catatan log dengan stempel waktu yang persis sama. Misalnya, jika pembuatan pesanan pembelian (sebagai transaksi) dapat mencakup pembuatan N item pesanan, maka semua catatan log 1 + N yang sesuai akan memiliki stempel waktu yang sama. Analisis selanjutnya dari log semacam itu dapat memanfaatkan ini, memperlakukan catatan 1 + N ini bukan sebagai yang independen tetapi sebagai elemen dari transaksi logis. Semoga ini masuk akal.
Yarik

24

Kami juga mencatat nilai lama dan baru dan dari kolom asalnya serta kunci utama dari tabel yang diaudit dalam tabel detail audit. Pikirkan untuk apa Anda membutuhkan tabel audit? Anda tidak hanya ingin tahu siapa yang membuat perubahan dan kapan, tetapi ketika perubahan buruk terjadi, Anda menginginkan cara cepat untuk mengembalikan data.

Saat Anda mendesain, Anda harus menulis kode untuk memulihkan data. Ketika Anda perlu pulih, biasanya terburu-buru, lebih baik sudah bersiap.


1
Ini sangat bagus. Saya tidak mengerti mengapa orang mengabaikan posting terakhir.
Maddy.Shik

3
Sumber acara adalah pendekatan alternatif untuk menyediakan fungsi roll-back sambil mempertahankan riwayat.
Sam

23

Ada beberapa hal lagi yang mungkin ingin Anda audit, seperti nama tabel / kolom, komputer / aplikasi tempat pembaruan dibuat, dan banyak lagi.

Sekarang, ini tergantung pada seberapa rinci audit yang benar-benar Anda butuhkan dan pada level apa.

Kami mulai membangun solusi audit berbasis pemicu kami sendiri, dan kami ingin mengaudit semuanya dan juga memiliki opsi pemulihan. Ini ternyata terlalu rumit, jadi kami akhirnya merekayasa balik Audit ApexSQL alat pihak ketiga berbasis pemicu untuk membuat solusi khusus kami sendiri.

Tips:

  • Sertakan nilai sebelum / sesudah

  • Sertakan 3-4 kolom untuk menyimpan kunci utama (jika itu adalah kunci komposit)

  • Simpan data di luar database utama seperti yang telah disarankan oleh Robert

  • Luangkan banyak waktu untuk menyiapkan laporan - terutama yang mungkin Anda perlukan untuk pemulihan

  • Rencanakan untuk menyimpan nama host / aplikasi - ini mungkin berguna untuk melacak aktivitas yang mencurigakan


2
Mengapa Anda merekayasa balik alih-alih membelinya?
Jowen

1
kontrol lebih besar atas produk
Tebe

1
Semoga mereka tidak menuntut Anda.
Penyortir

9

Ada banyak jawaban menarik di sini dan di pertanyaan serupa. Satu-satunya hal yang dapat saya tambahkan dari pengalaman pribadi adalah:

  1. Letakkan tabel audit Anda di database lain. Idealnya, Anda menginginkan pemisahan dari data asli. Jika Anda perlu memulihkan database Anda, Anda tidak benar-benar ingin memulihkan jejak audit.

  2. Denormalisasikan sebanyak mungkin. Anda ingin tabel memiliki dependensi sesedikit mungkin ke data asli. Tabel audit harus sederhana dan secepat kilat untuk mengambil data. Tidak ada gabungan atau pencarian mewah di tabel lain untuk mendapatkan data.


8
Akankah data yang tidak dinormalisasi benar-benar lebih cepat dibaca dibandingkan dengan data yang dinormalisasi dengan indeks yang sesuai? (Bukankah semua duplikasi menghasilkan lebih banyak data dari HDD?)
Sam

4

Apa yang kami miliki di tabel kami: -

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

Id generik menunjuk pada sebuah baris dalam tabel yang telah diperbarui dan nama tabel adalah nama tabel itu sebagai string. Bukan desain DB yang bagus, tapi sangat berguna. Semua tabel kami memiliki satu kolom kunci pengganti sehingga ini berfungsi dengan baik.


2
Apa yang diwakili oleh "jumlah"?
turdus-merula

Ini adalah aplikasi keuangan, jadi ini adalah nilai dolar dari hal yang diotorisasi, dll.
WW.

4

Secara umum, audit khusus (membuat berbagai tabel) adalah opsi yang buruk. Pemicu database / tabel dapat dinonaktifkan untuk melewati beberapa aktivitas log. Tabel audit khusus dapat dirusak. Pengecualian dapat terjadi yang akan menurunkan penerapan. Belum lagi kesulitan merancang solusi yang kuat. Sejauh ini saya melihat kasus yang sangat sederhana dalam diskusi ini. Anda memerlukan pemisahan lengkap dari database saat ini dan dari pengguna yang memiliki hak istimewa (DBA, Pengembang). Setiap RDBMS arus utama menyediakan fasilitas audit yang bahkan DBA tidak dapat menonaktifkannya, merusak secara rahasia. Oleh karena itu, kemampuan audit yang disediakan oleh vendor RDBMS harus menjadi pilihan pertama. Pilihan lainnya adalah pembaca log transaksi pihak ketiga atau pembaca log kustom yang mendorong informasi yang diuraikan ke dalam sistem pesan yang berakhir di beberapa bentuk Gudang Data Audit atau pengendali peristiwa waktu nyata. Singkatnya: Arsitek Solusi / "Arsitek Data Hands on" perlu terlibat dalam menentukan sistem seperti itu berdasarkan persyaratan. Biasanya terlalu serius untuk diserahkan kepada pengembang untuk mendapatkan solusi.


3

Ada banyak cara untuk melakukan ini. Cara favorit saya adalah:

  1. Tambahkan mod_userbidang ke tabel sumber Anda (yang ingin Anda catat).

  2. Buat tabel log yang berisi bidang yang ingin Anda catat, ditambah bidang log_datetimedan seq_num. seq_numadalah kunci utama.

  3. Buat pemicu pada tabel sumber yang menyisipkan rekaman saat ini ke dalam tabel log setiap kali bidang yang dipantau berubah.

Sekarang Anda memiliki catatan tentang setiap perubahan dan siapa yang membuatnya.


Jadi ... apa yang harus dilakukan bidang mod_user?
conny

1
Memberitahu Anda siapa yang membuat perubahan. Memperbarui kode harus menyertakan sesuatu untuk menyetel bidang itu ke pengguna saat ini.
JosephStyons

Bagaimana dengan menghapus? Jika Anda menghapus sebuah baris, bagaimana Anda menangani nilai untuk kolom mod_user?
Kenn Cal

Pemicu @KennCal dapat menggunakan tabel virtual, Anda dapat melihat data setelah, dan sebelumnya, di dalam pemicu yang sama. Tidak masalah operasinya. stackoverflow.com/questions/6282618/…
Renan Cavalieri

2
@KennCal Anda benar, pemicu penghapusan perlu menyimpan informasi itu untuk Anda. Masalahnya ada dalam detailnya - jika Anda menggunakan otentikasi SQL, pemicunya hanya dapat menjalankan [pilih CURRENT_USER]. Jika ini adalah aplikasi klien, maka kode klien perlu mengumumkan siapa itu. Jika ini adalah panggilan API, pengguna yang menghapus harus menjadi parameter yang diperlukan untuk panggilan tersebut.
JosephStyons

1

Menurut prinsip pemisahan:

  1. Tabel data audit harus terpisah dari database utama. Karena database audit dapat memiliki banyak data historis, maka masuk akal dari sudut pandang penggunaan memori untuk memisahkannya.

  2. Jangan gunakan pemicu untuk mengaudit seluruh database, karena Anda akan berakhir dengan kekacauan database yang berbeda untuk didukung. Anda harus menulis satu untuk DB2, SQLServer, Mysql, dll.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.