时态表上的主键是什么?

jl6*_*jl6 7 database-design

如果我使用下表设计来捕获历史...:

CREATE TABLE MyTable (
    insertion_timestamp TIMESTAMP,
    deleted_flag BOOLEAN,
    natural_key INT,
    attribute VARCHAR
);
Run Code Online (Sandbox Code Playgroud)

...那么主键应该是什么?

(历史记录机制是INSERT-only:更新的行插入不同的insertion_timestamp,删除的行插入不同的时间戳并deleted_flag设置为true。)

我在想PRIMARY KEY (insertion_timestamp, deleted_flag, natural_key),但包含的唯一原因deleted_flag是考虑到插入行然后(软)立即删除的可能性,比TIMESTAMP数据类型粒度的下一个刻度要早。这感觉太偏执了......

小智 3

\n

我在想PRIMARY KEY (insertion_timestamp, deleted_flag, natural_key),但包含deleted_flag的唯一原因是考虑到插入行然后立即(软)删除行的可能性,早于数据类型粒度的下一个刻度TIMESTAMP。这感觉太偏执了……

\n
\n\n

我不知道这是否太偏执了,但是规定没有两行可以共享相同的insertion_timestampnatural_key,并让客户端有责任进行插入来处理边缘情况,这是合理的。如果您可以假设这些组合在您建议的三方键中是唯一的\xe2\x80\x94plus,那么它会大大简化表的使用,在三重偏执的情况下对行进行排序是很棘手的,其中有两个直接的“软” ” 连续删除。

\n\n

所以我的建议是PRIMARY KEY (natural_key, insertion_timestamp)(按照这个顺序\xe2\x80\x94,但我猜natural_key会更频繁地查询,这可能是错误的)。

\n\n

另外,您应该认真考虑以下补充:

\n\n
    \n
  1. inactive_timestamp向表中添加一列。这允许您查询在某个时间点处于活动状态的行。
  2. \n
  3. 仔细考虑时间戳的含义。该表是否应该代表现实世界值的历史(“Joe 的电话号码在 1 月 22 日之前为 555-5555,然后从 1 月 22 日起为 666-6666”),还是对“永恒值”的修改历史? “ 价值?您的架构看起来像是后者,但请确保您了解需要哪个。
  4. \n
\n