Veritabanı girişlerindeki değişikliklerin geçmişine sahip olma yolları


21

Veritabanı girişlerinin (verilerin) sürümlendirilmesine izin vermenin yolları nelerdir?

Makale değişikliklerini geri alabilmek için içerik yönetim sistemlerinin yeteneklerini düşünün.

Artıları / eksileri nelerdir?


1
Tam olarak neyi sürümlemek istiyorsunuz? Şema mı yoksa veri mi?
tdammers

1
Verileri versiyonlamak istiyorum. Cms örneğinde kalmak için, makalelerin sürümlerini söyleyelim .
matcauthon

Datomic'e bakmak isteyebilirsiniz.
dan_waterworth

Yanıtlar:


19

Temel olarak iki yaklaşım vardır: içinde önceki tüm değerlerin saklandığı bir denetim tablosu veya tablonun bir parçası olarak bir başlangıç ​​/ bitiş tarihi içerir ve tüm güncellemeler eskisini kapatırken yeni bir kayıt oluşturur.

Güncelleme: SQL SERVER 2016 bunu bir tasarım deseni / tablo türü olarak desteklemektedir - https://docs.microsoft.com/en-us/sql/relational-databases/tables/temporal-tables?view=sql-server-2017


4
Yani ilk yaklaşım daha ölçeklenebilir olabilir. "Arşivlenen" verilere nadiren erişileceğinden, veritabanı tasarımı optimize edilebilir. Ve çalışma masası küçük kalıyor. Karmaşıklığa bağlı olarak, sadece farkları kaydetmek de mümkün olmalıdır. Hatıra deseninin kullanılması tavsiye edilir mi?
matcauthon

1
Bu, kullanımınıza bağlı olacaktır, tabloları doldurmak için tetikleyicileri kullanmak ve ardından ne ve ne kadar geri çekileceğini seçmek için bir yol sağlamak yeterli olabilir.
jmoreno

Cevabınızda bir yazım hatası var (
bilmece

7

Bir fikir "Yalnızca Eklenen Veritabanları" kullanmaktır. Temel fikir, bir satırdaki verileri asla silmemeniz veya güncellememenizdir .

İzlenecek gereklidir Her tablo iki sahip olacak datetimesütunlar fromve to. NULLHer birindeki değerle başlarlar (zamanın başlangıcından sonuna kadar). Satırı "değiştirmeniz" gerektiğinde, yeni bir satır eklersiniz ve aynı zamanda bir toönceki satıra Nowve fromeklediğiniz satıra da güncellersiniz Now.

Daha ayrıntılı bilgi için şuraya bakın:

Bu teknik, AuditTraileski verileri yönetmek için çağrılır ve tür depoları değişiklik geçmişini saklar.

Bu doğanın sorusu zaten yayınlanmış gibi görünüyor:


Ne yazık ki bu soru silinmiş görünüyor :(
Douglas Gaskell

Sorun değil, işte link . İçinde başka iyi tasarım öneri bağlantısını
Yusubov

2

Her tablo için tetikleyicileri kullanabileceğinizi ve _history'deki verileri koruyabileceğinizi düşünüyorum (veya herhangi bir ad verebilirsiniz) ve her ekleme, güncelleme, ana tablodaki silme tetikleyicinizi tetikler ve bu tablodaki ayrıntıları kaydedebilirsiniz. SQLite veritabanıyla da kullanılabilir.

Bu mekanizma büyük projeler için de yararlıdır. Bu tabloda, değişiklikleri yapan kullanıcının bilgilerini, değişikliklerin zaman damgasıyla birlikte günlüğe kaydedebilirsiniz. daha sonra tablonuzu gereksinimlerinize uygun zaman damgası herhangi birine geri yükleyebilirsiniz.

Her Veritabanının tetikleyicileri yazmak ve kodlamak için kendi yolu vardır. SQLite kullanıyorsanız sözdizimi için SQLite.org adresini ziyaret edin . Diğer veritabanları için resmi sitelerini ziyaret edebilirsiniz.


1

Muhtemelen Sqlite db motorunun farkındasınızdır . Tüm db tek bir dosyaya kaydedilir. Api ayrıca sanal dosya sistemlerini de destekler, böylece depolamayı her yerde ve herhangi bir formatta düzenleyebilirsiniz, sadece belirli dosya ofsetlerindeki okuma ve yazma işlemlerine yanıt verin. Bunun için olası uygulamalar şifreleme, sıkıştırma vb. Olabilir. Kapsayıcı katmanının veritabanları, sql veya sqlite dosya biçimi hakkında hiçbir şey bilmemesi gereken en iyi yanı, sadece xRead ve xWrite geri çağrılarına uymaktır.

Fikirlerden biri zaman makinesi özelliğini uygulamaktı. Bu nedenle, herhangi bir xWrite işlemi, "geri al" geçmişinde üzerine yazacağı her segmenti kaydeder ve kullanıcı db'nin içerdiği şeyi (muhtemelen salt okunur mod) görmek için geçmişte bir tarih seçebilir. Henüz çalışma örneğim yok ( sqlite posta listesinde bu konuda bir tartışma vardı ), ancak muhtemelen diğer motorlar VFS API'leri sağlayarak benzer bir şey mümkün. Ve bir kez uygulandığında, herhangi bir karmaşıklığın veritabanı yapılarıyla uyumlu olmalıdır.


Sizce bu yaklaşım daha büyük projeler için ölçeklenebilir mi?
matcauthon

Bu, büyük veri değişiklikleri için büyük veri yükü ekleyebileceğini düşünüyorum (açıkçası her bir değişiklik kaydedilmeli, ancak eski sürümler için sıkıştırma yardımcı olabilir). Bunun dışında, şemanız açısından, iki tablo için çalıştığı sürece, yirmi kişiliktir.
Maksee

1

Veritabanı girişlerini sürümlemek için kullandığımız yöntem bir denetim tablosu kullanmaktır. Tablo, aşağıdaki satırlarda bir şemaya sahiptir:

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

Ardından, izlemek istediğimiz tabloları Ekle / Güncelle / Sil ile ilgili tetikleyicilerimiz var.

Artıları:

  • Tüm veriler tek bir tabloda
  • Bir tablodaki tüm alanları veya belirli alanları izlemek için ayarlanabilir
  • Bir tablo için her alanda kolay sürüm oluşturma

Eksileri:

  • Tüm denetim bilgilerinin tek bir tabloda bulunması çok fazla kayıtla sonuçlanır
  • Çok sayıda tetikleyici gerekiyor

0

Şimdi bunun bir versiyonunu yapıyorum. her kayıt için bir Ekleme Tarihi, Değiştirme tarihi ve Aktif Kayıt boole bayrağı var. İlk ekleme için Eklenen ve Değiştirilen tarihlerin her ikisi de Şimdi () (Bu örnek Access'te) ve Etkin kayıt bayrağı olarak ayarlanır true. bu kaydı değiştirirsem her şeyi yeni bir kayda kopyalar, kullanıcının değiştirdiği alanları değiştiririm, Ekleme tarihini orijinaline eşit olarak değiştiririm ve Değiştirme tarihini Şimdi () olarak değiştiririm. Daha sonra orijinal kaydın Aktif Kayıt bayrağını falseve yeni kaydın üzerine çeviririm true. Ayrıca orijinal kaydın kimliğini kaydetmek ModifiedRecordsParentID için bir alan var.

Sonra bile sorgulamak ActiveRecord = truegerekirse ben sadece nerede kayıtları iade edebilir ve ben sadece en güncel bilgi alacak.


ActiveRecordBayrağa gerek yok . MAX (*) satırı her zaman geçerli kayıt olmalıdır. Önceki bir sürüme geri yükleme, söz konusu satırı tekrar tabloya ekler.
invert

Seçimi nasıl yapacağımdan emin değildim, ama şimdi bunu çağırıyorsun, bunu düşünüyorum ve bir fikrim var, hmmmm
Brad

Genellikle MAX (sütun_adı) tablonun sütunundaki en büyük değeri seçer. Tüm satırı seçmek için basit bir işlem yapılır select top 1 order by id descending.
invert

Evet, bu basit bir tek kayıt için işe yarıyor, ancak masam bir kerede seçilmesi gereken ancak bireysel olarak değiştirilebilen bir çocuk kayıtları koleksiyonuydu. Biraz daha karmaşık.
Brad

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.