バージョニングと呼ばれる手法がありますが、これは長年使用されていますが、いくつかの理由でほとんど機能しません。ただし、バージョン正規形と呼ばれる同様の手法があり、非常に便利であることがわかりました。 Employeesテーブルを使用した例を次に示します。
まず、静的テーブルが作成されます。これはメインエンティティテーブルであり、エンティティに関する静的データが含まれています。静的データとは、生年月日など、エンティティの存続期間中に変更されることが予想されないデータです。
create table Employees(
ID int auto_generated primary key,
FirstName varchar( 32 ),
Hiredate date not null,
TermDate date, -- last date worked
Birthdate date,
... -- other static data
);
このようなテーブルと同様に、従業員ごとに1つのエントリがあることを理解することが重要です。
次に、関連するバージョンテーブル。これにより、従業員には複数のバージョンが存在する可能性があるため、静的テーブルとの1mの関係が確立されます。
create table Employee_versions(
ID int not null,
EffDate date not null,
char( 1 ) IsWorking not null default true,
LastName varchar( 32 ), -- because employees can change last name
PayRate currency not null,
WorkDept int references Depts( ID ),
..., -- other changable data
constraint PK_EmployeeV primary key( ID, EffDate )
);
バージョン表の注記には、発効日がありますが、一致する無効になったフィールドはありません。これは、バージョンが有効になると、次のバージョンに置き換えられるまで有効なままになるためです。 IDとEffDateの組み合わせは一意である必要があります。これにより、同じ従業員に対して同時にアクティブな2つのバージョンが存在したり、1つのバージョンが終了してから次のバージョンが開始するまでの間にギャップが生じたりすることはありません。
ほとんどのクエリは、従業員データの現在のバージョンを知りたいと思うでしょう。これは、従業員の静的行を現在有効なバージョンと結合することによって提供されます。これは、次のクエリで見つけることができます:
select ...
from Employees e
join Employee_versions v1
on v1.ID = e.ID
and v1.EffDate =(
select Max( v2.EffDate )
from EmployeeVersions v2
where v2.ID = v1.ID
and v2.EffDate <= NOW()
)
where e.ID = :EmpID;
これにより、最新の過去に開始された唯一のバージョンが返されます。日付チェックで不等式<=を使用する(v2.EffDate <= NOW()
)将来の発効日を考慮に入れます。新入社員が来月の初日に就職するか、昇給が来月の13日に予定されていることがわかっている場合、このデータを事前に挿入できます。このような「プリロードされた」エントリは無視されます。
サブクエリを取得させないでください。すべての検索フィールドにインデックスが付けられているため、結果は非常に高速です。
この設計には多くの柔軟性があります。上記のクエリは、現在および過去のすべての従業員の最新データを返します。 TermDate
を確認できます 現在の従業員だけを取得するフィールド。実際、アプリ内の多くの場所は現在の従業員の現在の情報にのみ関心があるため、そのクエリは適切なビューになります(最後のwhere
は省略してください)。 句)。アプリがそのようなバージョンが存在することさえ知る必要はありません。
特定の日付があり、その時点で有効だったデータを確認したい場合は、v2.EffDate <= NOW()
を変更します。 v2.EffDate <= :DateOfInterest
へのサブクエリで 。
詳細については、こちらのスライドプレゼンテーションと、まだ完成していないドキュメントをご覧ください。
デザインの拡張性を少し示すために、IsWorking
があることに注意してください。 バージョンテーブルのインジケータと静的テーブルの終了日。従業員が会社を辞めると、最終日が静的テーブルに挿入され、IsWorking
を含む最新バージョンのコピーが挿入されます。 false
に設定 バージョンテーブルに挿入されます。
従業員がしばらく会社を辞めてから再び雇用されることはかなり一般的です。静的テーブルの日付だけで、その日付をNULLに戻すだけで、エントリを再度アクティブ化できます。しかし、その人がもはや従業員ではなくなったときの「振り返り」クエリは、結果を返します。彼らが会社を辞めたという兆候はありません。ただし、IsWorking
を含むバージョン =会社を辞めるときはfalse、IsWorking
=会社に戻ったときにtrueになると、関心のあるときにその値を確認でき、後で戻ったとしても、従業員でなくなった従業員は無視されます。