[英]Foreign key from a NON audit trail table to an audit trail table
在現有模式中,我僅對其中一個表引入審計跟蹤/里程碑支持。 為了討論問題,我們將使用以下簡化的玩具示例來更好地說明問題。
DEPARTMENT
ID | NAME | CREATED_TS | MODIFIED_TS | VERSION
1 | "ABC" | 11/20/2015 | 12/1/9999 | 1
現在,每次收到對id = 1的department
記錄的更新請求時,系統都會執行以下操作。 基本上每個更新是一個INSERT
-這改變現有記錄的MODIFIED_TS
的時間UPDATE
請求進來,最新記錄的MODIFIED_TS
始終保持為12/1/9999
(又名INFINITY
TIMESTAMP)
假設更新ID = 1記錄更改了名稱,下面是db中的樣子。
DEPARTMENT
ID | NAME | CREATED_TS | MODIFIED_TS | VERSION
1 | "ABC" | 11/20/2015 | 11/22/2015 | 1
1 | "XYZ" | 11/22/2015 | 12/1/9999 | 2
現在假設存在一個現有的EMPLOYEE
表,其中DEPT_ID
為外鍵。 請注意, EMPLOYEE
表沒有審核跟蹤要求,因此那里沒有INFINITY
時間戳或VERSION
概念。 EMPLOYEE
表如下所示
EMPLOYEE
ID | NAME | AGE | DEPT_ID
1 | "John" | 31 | 1
就雇員與DEPT有FK關系而言,一切都很好,而DEPT以前將ID作為PK。 現在, DEPARTMENT
表的PK已更改為復合PK(ID,VERSION)
在對DEPARTMENT
表進行這些模式更改以為其數據創建auit跟蹤之后, EMPLOYEE
FK必須以某種方式創建FK,其中不僅DEPT_ID
還要包括DEPT
記錄的INFINITY
時間戳( MODIFIED_TS
),因為EMPLOYEE
將始終引用最新的DEPT
記錄(要求)
更改EMPLOYEE
表的FK以指向DEPT
表中的最新記錄的最佳方法是什么?
這是解決您的問題的可怕的數據建模技巧。 不要在家嘗試這個...
由於部門的PK是{id,modified_ts},因此員工的FK也必須是復合的(否則它可能指向另一組唯一的列)。 因此,解決方案是根據需要提供給它:恆定值為'infinity'的列。 (“ infinity”是postgres中日期和時間戳的有效值,您無需發明自己的哨兵值)
CREATE TABLE department
( id INTEGER NOT NULL
, name varchar
, created_ts timestamp
, modified_ts timestamp
, version integer not null default 0
, PRIMARY KEY (id, modified_ts)
);
INSERT INTO department (id, name, created_ts, modified_ts, version) VALUES
(1 , 'ABC', '2015-11-20' , '2015-11-22' , 1) ,
(1 , 'XYZ', '2015-11-22' , 'infinity' , 2) ;
-- CREATE UNIQUE INDEX ON department (id) WHERE modified_ts = 'infinity'::timestamp;
-- Now assume there is an existing EMPLOYEE table with DEPT_ID as a foreign key. Note that EMPLOYEE table doesn't have an audit trail requirement so there is no INFINITY timestamp or VERSIONing concept there. EMPLOYEE table looks like as below
CREATE TABLE employee
( id INTEGER NOT NULL PRIMARY KEY
, name varchar
, age integer not null default 0
, modified_ts timestamp NOT NULL DEFAULT 'infinity'::timestamp CHECK (modified_ts = 'infinity'::timestamp)
, dept_id INTEGER NOT NULL
, FOREIGN KEY (id,modified_ts)
REFERENCES department(id, modified_ts)
);
INSERT INTO employee(id ,name,age,dept_id) VALUES
(1 , 'John' , 31 , 1);
DEFERRABLE INITIALLY DEFERRED
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.