简体   繁体   English

用于行版本控制的RDBMS主键设计

[英]RDBMS primary key design for row versioning

I want to design primary key for my table with row versioning. 我想使用行版本控制为我的表设计主键。 My table contains 2 main fields : ID and Timestamp, and bunch of other fields. 我的表包含2个主要字段:ID和时间戳,以及其他字段。 For a unique "ID" , I want to store previous versions of a record. 对于唯一的“ ID”,我想存储记录的先前版本。 Hence I am creating primary key for the table to be combination of ID and timestamp fields. 因此,我正在为表创建ID和时间戳字段组合的主键。 Hence to see all the versions of a particular ID, I can give, 因此,要查看特定ID的所有版本,我可以给出,

Select * from table_name where ID=<ID_value>

To return the most recent version of a ID, I can use 要返回ID的最新版本,我可以使用

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

and get the first element. 并获得第一个元素。 My question here is, will this query be efficient and run in O(1) instead of scanning the entire table to get all entries matching same ID considering ID field was a part of primary key fields? 我的问题是,此查询是否有效并且可以在O(1)中运行,而不是扫描整个表以考虑到ID字段是主键字段的一部分来获取所有匹配相同ID的条目吗? Ideally to get a result in O(1), I should have provided the entire primary key. 理想情况下,要在O(1)中获得结果,我应该提供整个主键。 If it does need to do entire table scan, then how else can I design my primary key so that I get this request done in O(1)? 如果确实需要进行整个表扫描,那么我还能如何设计主键,以便在O(1)中完成此请求?

Thanks, Sriram 谢谢,Sriram

The canonical reference on this subject is Effective Timestamping in Databases : https://www.cs.arizona.edu/~rts/pubs/VLDBJ99.pdf 关于此主题的规范参考是数据库中的有效时间戳记https : //www.cs.arizona.edu/~rts/pubs/VLDBJ99.pdf

I usually design with a subset of this paper's recommendations, using a table containing a primary key only, with another referencing table that has that key as well change_user, valid_from and valid_until colums with appropriate defaults. 我通常使用本文建议的子集进行设计,使用仅包含主键的表,以及具有该键以及具有适当默认值的change_user,valid_from和valid_until列的另一个引用表。 This makes referential integrity easy, as well as future value insertion and history retention. 这使引用完整性变得容易,并且可以增加将来的值和保留历史记录。 Index as appropriate, and consider check constraints or triggers to prevent overlaps and gaps if you expose these fields to the application for direct modification. 如果您将这些字段暴露给应用程序以进行直接修改,请适当地建立索引,并考虑检查约束或触发器以防止重叠和空白。 These have an obvious performance overhead. 这些都有明显的性能开销。

We then make a "current values view" which is exposed to developers, and is also insertable via an "instead of" trigger. 然后,我们制作一个“当前值视图”,该视图向开发人员公开,并且也可以通过“代替”触发器插入。

It's far easier and better to use the History Table pattern for this. 为此,使用“历史记录表”模式要容易得多,而且效果更好。

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)
);

Create a trigger to copy a foo row to foo_history on update or delete. 创建触发器以在更新或删除时将foo行复制到foo_history。

https://wiki.postgresql.org/wiki/Audit_trigger_91plus for a full example with postgres https://wiki.postgresql.org/wiki/Audit_trigger_91plus以获得postgres的完整示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM