Değişiklik günlüğü / denetim veritabanı tablosu için en iyi tasarım? [kapalı]


114

Farklı değişiklik günlüğü / denetimi (bir şey eklendiğinde, silindiğinde, değiştirildiğinde vb.) Depolamak için bir veritabanı tablosu oluşturmam gerekiyor. Özellikle ayrıntılı bilgileri depolamaya ihtiyacım yok, bu yüzden şu satırlarda bir şeyler düşünüyordum:

  • id (etkinlik için)
  • onu tetikleyen kullanıcı
  • etkinlik adı
  • Etkinlik Açıklaması
  • olayın zaman damgası

Burada bir şey mi kaçırıyorum? Açıkçası tasarımı geliştirmeye devam edebilirim, ancak bunu karmaşık hale getirmeyi planlamıyorum (olay türleri için başka tablolar veya bunun gibi şeyler oluşturmak, ihtiyacım için bir karmaşıklık olduğu için söz konusu değil).


Cevabınızı okudum ve kimsenin Hukuk hakkında konuşmamasına şaşırdım. Bazı kanunların veya iyi uygulama belgelerinin bir (salt okunur) denetim tablosunu nasıl uygulamamız GEREKTİRDİĞİNİ açıkladığını biliyorum. Ama bundan daha fazla bilgim yok. Sadece var olduğunu biliyorum. CFR 21 bölüm 11'deki Denetim izini düşünüyorum.
Bastien Vandamme

Yanıtlar:


70

Üzerinde çalıştığım projede, denetleme günlüğü de tarif ettiğiniz gibi çok minimalist tasarımdan başladı:

event ID
event date/time
event type
user ID
description

Fikir aynıydı: işleri basit tutmak.

Ancak bu minimalist tasarımın yeterli olmadığı kısa sürede anlaşıldı. Tipik bir denetim şu gibi sorulara dönüşüyordu:

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

Dolayısıyla, bu tür sorulara hızlı bir şekilde cevap verebilmek için (SQL kullanarak), denetim tablosunda iki ek sütun elde ettik.

object type (or table name)
object ID

İşte o zaman denetim günlüğümüzün tasarımı gerçekten stabil hale geldi (şimdi birkaç yıldır).

Elbette, son "iyileştirme" yalnızca yedek anahtarları olan masalarda işe yarar. Ama tahmin et ne oldu? Denetlenmeye değer tüm masalarımızda böyle bir anahtar var!


Bu tasarımla ilgili yaşadığım tek sorun ('açıklama' tabanlı bir denetim izi) o alanda kullanılan dilin yerelleştirilmesidir.
Sam Wilson

@Sam Böyle bir sorun görmüyorum, eğer mesaj sistem oluşturulmuşsa, burada sadece çeviri dizesi için bir anahtar kullanın;
JCM

4
@Hiru: İki veya daha fazla farklı kavramı tek bir sütuna "karıştırdığınızda", çoğu zaman er ya da geç geri tepecektir. Örneğin, olay türünü ve nesne türünü "karıştırırsanız", "verilen türdeki tüm nesneler için kayıtları göster" ve "belirli bir türdeki tüm olaylar için kayıtları bana göster" gibi sorguları etkiler (sorgular daha fazla karmaşıktır ve büyük olasılıkla çok daha yavaş çalışır).
Yarik

3
Bu sütunlara ek olarak, yapılandırılmış açıklama / yapılandırılmış etkinlik yükü için fazladan bir sütun olabilir . Bu sütun, olay ayrıntılarını (karmaşıklığı ne olursa olsun) bilgisayar tarafından okunabilir bir formatta, XML / JSON'da tutacaktır. Kolay seri hale getirme, sorgulama (en azından Postgres / MSSQL'de), akıl yürütme.
turdus-merula

1
@Benjamin: Cevap alan modelinde (aka iş modeli). Model, varlıkların eşzamanlı olarak oluşturulmasına izin veriyorsa (örneğin, mantıksal işlemin bir parçası olarak), tam olarak aynı zaman damgasına sahip birden fazla günlük kaydına sahip olmakta herhangi bir sorun görmüyorum. Örneğin, bir satınalma siparişinin yaratılması (bir işlem olarak) N sipariş kaleminin yaratılmasını içerebiliyorsa, o zaman tüm karşılık gelen 1 + N günlük kayıtları aynı zaman damgasına sahip olacaktır. Bu tür günlüğün sonraki analizi, bu 1 + N kayıtları bağımsız olanlar olarak değil, mantıksal bir işlemin öğeleri olarak ele alarak bundan yararlanabilir. Umarım bu mantıklıdır.
Yarik

24

Ayrıca eski ve yeni değerleri ve bunların ait olduğu sütunu ve denetlenmekte olan tablonun birincil anahtarını bir denetim ayrıntı tablosuna kaydederiz. Denetim tablosuna ne için ihtiyacınız olduğunu düşünün? Yalnızca kimin ve ne zaman değişiklik yaptığını bilmek istemezsiniz, aynı zamanda kötü bir değişiklik olduğunda, verileri geri koymanın hızlı bir yolunu istersiniz.

Tasarlarken, verileri kurtarmak için kodu yazmalısınız. İyileşmeniz gerektiğinde, genellikle aceleniz olur, en iyisi zaten hazırlanmaktır.


1
Bu gerçekten çok iyi, insanların neden son gönderileri görmezden geldiğini anlamıyorum.
Maddy.Shik

3
Olay kaynak bulma , geçmişi korurken geri alma işlevselliği sağlamaya alternatif bir yaklaşımdır.
Sam

23

Tablo / sütun adları, güncellemenin yapıldığı bilgisayar / uygulama ve daha fazlası gibi denetlemek isteyebileceğiniz birkaç şey daha vardır.

Şimdi, bu gerçekten ne kadar detaylı denetime ihtiyacınız olduğuna ve hangi düzeyde ihtiyacınız olduğuna bağlı.

Kendi tetik tabanlı denetim çözümümüzü oluşturmaya başladık ve her şeyi denetlemek ve ayrıca elimizde bir kurtarma seçeneği olmasını istedik. Bunun çok karmaşık olduğu ortaya çıktı, bu yüzden kendi özel çözümümüzü oluşturmak için tetik tabanlı, üçüncü taraf ApexSQL Audit aracına ters mühendislik uyguladık .

İpuçları:

  • Önce / sonra değerleri dahil et

  • Birincil anahtarı depolamak için 3-4 sütun ekleyin (bileşik anahtar olması durumunda)

  • Robert tarafından önerildiği gibi verileri ana veri tabanının dışında saklayın

  • Raporları hazırlamak için makul bir zaman harcayın - özellikle de kurtarma için ihtiyaç duyabileceğiniz olanlar

  • Ana bilgisayar / uygulama adını depolamak için plan yapın - bu, şüpheli etkinlikleri izlemek için çok yararlı olabilir


2
Satın almak yerine neden tersine mühendislik yapasınız?
Jowen

1
ürün üzerinde daha fazla kontrol
Tebe

1
Umarım dava açmamışlardır.
Sıralayıcı

9

Burada ve benzer sorularda birçok ilginç cevap var. Kişisel deneyimlerimden ekleyebileceğim tek şey:

  1. Denetim tablonuzu başka bir veritabanına koyun. İdeal olarak, orijinal verilerden ayrılmak istersiniz. Veritabanınızı geri yüklemeniz gerekiyorsa, denetim izini gerçekten geri yüklemek istemezsiniz.

  2. Makul bir şekilde mümkün olduğunca normal olmayan hale getirin. Tablonun orijinal verilere olabildiğince az bağımlı olmasını istiyorsunuz. Verileri almak için denetim tablosu basit ve yıldırım hızında olmalıdır. Verilere ulaşmak için diğer tablolarda süslü birleştirme veya arama yok.


8
Normalleştirilmemiş veriler, uygun dizinlere sahip normalleştirilmiş verilere kıyasla gerçekten daha hızlı okunabilir mi? (Yinelemelerin tümü HDD'den daha fazla veri okunmasına neden olmaz mı?)
Sam

4

Masamızda ne var: -

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

Genel kimlik, güncellenen tablodaki bir satıra işaret eder ve tablo adı, bu tablonun bir dize olarak adıdır. İyi bir DB tasarımı değil ama çok kullanışlı. Tüm tablolarımızda tek bir yedek anahtar sütunu vardır, bu yüzden bu iyi çalışır.


2
"Miktar" neyi temsil eder?
turdus-merula

Bu bir finansal uygulama, yani izin verilen şeyin dolar değeri, vb.
WW.

4

Genelde özel denetim (çeşitli tablolar oluşturmak) kötü bir seçenektir. Bazı günlük etkinliklerini atlamak için veritabanı / tablo tetikleyicileri devre dışı bırakılabilir. Özel denetim tabloları değiştirilebilir. Uygulamayı düşürecek istisnalar olabilir. Sağlam bir çözüm tasarlamanın zorluklarından bahsetmiyorum bile. Şimdiye kadar bu tartışmada çok basit durumlar görüyorum. Mevcut veri tabanından ve tüm ayrıcalıklı kullanıcılardan (DBA, Geliştiriciler) tam bir ayrılığa ihtiyacınız var. Her ana akım RDBMS, DBA'nın bile devre dışı bırakamadığı, gizliliği kurcalayamadığı denetim olanakları sağlar. Bu nedenle, RDBMS satıcısı tarafından sağlanan denetim yeteneği ilk seçenek olmalıdır. Diğer bir seçenek ise, ayrıştırılmış bilgileri bazı Denetim Veri Ambarı veya gerçek zamanlı olay işleyicisi biçimlerinde sonuçlanan mesajlaşma sistemine aktaran üçüncü taraf işlem günlüğü okuyucu veya özel günlük okuyucu olabilir. Özetle: Çözüm Mimarı / "Uygulamalı Veri Mimarı", gereksinimlere dayalı olarak böyle bir sistemin hedeflenmesinde yer almalıdır. Çözüm için bir geliştiriciye teslim etmek genellikle çok ciddi şeylerdir.


3

Bunu yapmanın birçok yolu var. En sevdiğim yol:

  1. mod_userKaynak tablonuza (günlüğe kaydetmek istediğiniz) bir alan ekleyin .

  2. Günlüğe kaydetmek istediğiniz alanların yanı sıra bir log_datetimeve seq_numalanını içeren bir günlük tablosu oluşturun . seq_numbirincil anahtardır.

  3. Kaynak tabloda, izlenen herhangi bir alan değiştirildiğinde geçerli kaydı günlük tablosuna ekleyen bir tetikleyici oluşturun.

Artık her değişikliğin ve bunu kimin yaptığının bir kaydına sahipsiniz.


Öyleyse ... mod_user alanının ne yapması gerekiyor?
conny

1
Değişikliği kimin yaptığını söyleyin. Güncelleme kodu, bu alanı mevcut kullanıcıya ayarlamak için bir şey içermelidir.
JosephStyons

Peki ya silmeler? Bir satırı silerseniz, mod_user sütununun değerini nasıl işlersiniz?
Kenn Cal

@KennCal Tetikleyicileri sanal tabloları kullanabilir, aynı tetikleyicinin içindeki verileri önceki ve sonraki verileri görebilirsiniz. Operasyonun önemi yok. stackoverflow.com/questions/6282618/…
Renan Cavalieri

2
@KennCal Doğru, silme tetikleyicisinin bu bilgileri sizin için saklaması gerekecek. Şeytan ayrıntıda gizlidir - SQL kimlik doğrulaması kullanıyorsanız, tetikleyici yalnızca [CURRENT_USER seçeneğini] çalıştırabilir. Bir istemci uygulamasıysa, istemci kodunun kim olduğunu bildirmesi gerekir. Bir API çağrısıysa, silinen kullanıcının çağrı için gerekli bir parametre olması gerekir.
JosephStyons

1

Ayrılık ilkesine göre:

  1. Denetim veri tablolarının ana veritabanından ayrı olması gerekir. Denetim veritabanları çok sayıda geçmiş veriye sahip olabileceğinden, onları ayrı tutmak bellek kullanımı açısından anlamlıdır.

  2. Tüm veritabanını denetlemek için tetikleyicileri kullanmayın, çünkü sonunda desteklemek için farklı veritabanları karmaşasıyla karşılaşacaksınız. DB2, SQLServer, Mysql vb. İçin bir tane yazmanız gerekecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.