Tarih / geçici tablolar için en iyi uygulamalar?


11

Geçmişi izlemek istediğim belirli alanlara ve geçmişi izlemek istemediğim belirli alanlara sahip bir nesnem olduğunu varsayalım. Normalleştirme perspektifinden bakıldığında, aşağıdaki şema uygundur:

CREATE TABLE MyObject AS (
    MyObjectId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectField1 VARCHAR(100) NOT NULL,
    MyObjectField2 VARCHAR(100) NOT NULL,
    MyObjectField3 VARCHAR(100) NOT NULL,
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)
CREATE TABLE MyObjectHistory AS (
    MyObjectHistoryId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectId INT NOT NULL FOREIGN KEY REFERENCES MyObject(MyObjectId),
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)

burada MyObjectHistory, en son düzeltme dışındaki herkes için izlenen alanları içerir. Veya, izlenen tüm alanlar tek bir tabloda olmalı ve en son dahil olmak üzere tüm düzeltmeler aşağıdaki gibi bu tabloda olmalıdır:

CREATE TABLE MyObject AS (
    MyObjectId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectField1 VARCHAR(100) NOT NULL,
    MyObjectField2 VARCHAR(100) NOT NULL,
    MyObjectField3 VARCHAR(100) NOT NULL,
)
CREATE TABLE MyObjectHistory AS (
    MyObjectHistoryId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectId INT NOT NULL FOREIGN KEY REFERENCES MyObject(MyObjectId),
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)

@Joel
HaBo

Yanıtlar:


7

Pratik veri erişimi nedenleriyle, yapıyı ilk seçeneğinizden kullanmalısınız, bunun yerine geçmiş tablonuzdaki geçerli sürüm de dahil olmak üzere izlenen sütun değerlerinizin tüm sürümlerini saklamalısınız .

Bunun nedeni, genel olarak, tarihe bakmak istediğinizde, şimdiki ve geçmiş tüm sürümleri dahil etmek istemenizdir. Tarihe bakmak istemediğinizde, onu yoldan çıkarmak istersiniz. Birçok durumda bu, geçmişi tamamen ayrı bir şema veya veritabanına ayıracak kadar ileri gitmek anlamına gelir. Geçmişinizi mevcut verilerinizle aynı şemada tutsanız bile, geçmiş verilere (mevcut değerler dahil) bakan tüm sorgular, aslında iki kaynağı birleştirmek zorunda olduklarından çok daha karmaşık olacaktır.


2

İlk sürümü tercih ederim çünkü muhtemelen sadece nadiren geçmişi görmeniz gerekir, ancak sık sık geçerli değeri görmeniz gerekir. Bir tetikleyiciden geçmiş tablosu doldurulmalıdır, bu nedenle verilerin genel olarak senkronizasyondan çıkması konusunda endişelenmenize gerek yoktur. Diyelim ki MyObject'te bir milyon kaydınız var ve ardından MyObjectHistory'de 10.000.000 kaydınız var. Geçerli değeri almak için bu kadar kayıt içeren bir tabloya gerçekten katılmak istiyor musunuz?

Şimdi, tarihi geçerli değerden daha sık veya daha sık olarak sorgulamanız gerekiyorsa, ikinci strüttür işe yarayacaktır. (Ve belirli bir tarih itibarıyla değeri görüntüleyecekseniz, sorgulamayı kolaylaştırmak için bir başlangıç ​​ve bitiş tarihi alanına sahip olurum.)

BTW Değişikliklerin hangi sırada olduğunu söyleyebilmek için tarih tablosuna bir tarih alanı eklerdim. Geçici düzen için kimliklere güvenemezsiniz. PLus bir previosu değeri hakkında bir soru varsa ve değiştiğinde, bilmeniz gerekir. Değişikliğin geldiği uygulama (birden fazla uygulamanız varsa) ve / veya değişikliği yapan kişi için de değerler koyabilirim.


0

# 1 için birkaç önemli neden var. Birincisi HLGEM'in işaret ettiği boyut sorunu, ancak başka önemli konular da var.

Genellikle denetim yolunuz zaman içinde gereksinimlerin gelişmesini sağlayacaktır. Son olarak veritabanı kullanıcılarını, değişiklik zamanlarını vb. İzlemek isteyebilirsiniz. Denetim izi gereksinimleri ve ana tablonuz zaman içinde biraz bağımsız olarak değişebilir. Son olarak, denetim izi verilerini bir süre sonra bağımsız olarak ve tamamen ayrı bir tablodan temizlemek isteyebilirsiniz.

Tabii ki bunları tam olarak birleştirmek istediğiniz durumlar olabilir (LedgerSMB'deki vergi oranları için yaptığımız gibi), geçmiş veriler mevcut hesaplamalar için kullanılabilir ve kayıt sayısının nispeten küçük olması muhtemeldir.

Bununla birlikte, bu gibi tablolarda nesne depolamanın nadiren iyi, normalleştirilmiş tasarımlara yol açtığını önereceğim. Deneyimlerime göre, iyi normalleştirilmiş depolama ve bir uygulama nesnesi modeli arasında gerçekten bir kapsülleme istersiniz.


2
“İyi normalleştirilmiş depolama ve bir uygulama nesnesi modeli arasındaki kapsülleme” ile ne demek istersiniz? Bu fikri açıklar mısınız yoksa bir örnek verir misiniz?
cubetwo1729
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.