2

我想用行版本控制为我的表设计主键。我的表包含 2 个主要字段:ID 和时间戳,以及一堆其他字段。对于唯一的“ID”,我想存储以前版本的记录。因此,我正在为表创建主键以作为 ID 和时间戳字段的组合。因此,要查看特定 ID 的所有版本,我可以给出,

Select * from table_name where ID=<ID_value>

要返回 ID 的最新版本,我可以使用

Select * from table_name where ID=<ID_value> ORDER BY timestamp desc

并获得第一个元素。我的问题是,考虑到 ID 字段是主键字段的一部分,这个查询是否会高效并在 O(1) 中运行,而不是扫描整个表以获取与相同 ID 匹配的所有条目?理想情况下,为了得到 O(1) 的结果,我应该提供整个主键。如果它确实需要进行整个表扫描,那么我还能如何设计我的主键以便我在 O(1) 中完成这个请求?

谢谢,斯里拉姆

4

2 回答 2

2

关于这个主题的规范参考是数据库中的有效时间戳https ://www.cs.arizona.edu/~rts/pubs/VLDBJ99.pdf

我通常使用本文建议的子集进行设计,使用仅包含主键的表,以及具有该键的另一个引用表以及具有适当默认值的 change_user、valid_from 和 valid_until 列。这使得参照完整性以及未来价值插入和历史保留变得容易。如果您将这些字段公开给应用程序以进行直接修改,请根据需要进行索引,并考虑检查约束或触发器以防止重叠和间隙。这些具有明显的性能开销。

然后,我们制作了一个“当前值视图”,它向开发人员公开,也可以通过“代替”触发器插入。

于 2015-07-21T01:02:34.233 回答
1

为此使用历史表模式要容易得多,也更好。

create table foo (
  foo_id int primary key,
  name text
);

create table foo_history (
  foo_id int,
  version int,
  name text,
  operation char(1) check ( operation in ('u','d') ),
  modified_at timestamp,
  modified_by text
  primary key (foo_id, version)
);

创建触发器以在更新或删除时将 foo 行复制到 foo_history。

https://wiki.postgresql.org/wiki/Audit_trigger_91plus获取 postgres 的完整示例

于 2015-07-22T19:05:58.887 回答