temporal_tables
概览
| 扩展包名 | 版本 | 分类 | 许可证 | 语言 |
|---|---|---|---|---|
temporal_tables | 1.2.2 | TIME | BSD-2-Clause | C |
| ID | 扩展名 | Bin | Lib | Load | Create | Trust | Reloc | 模式 |
|---|---|---|---|---|---|---|---|---|
| 1040 | temporal_tables | 否 | 是 | 否 | 是 | 否 | 是 | - |
| 相关扩展 | periods table_version data_historization pgmemento table_log emaj old_snapshot pg_dirtyread pg_visibility ddl_historization |
|---|
no pg17 on el8/9 pgdg repo
版本
| 类型 | 仓库 | 版本 | PG 大版本 | 包名 | 依赖 |
|---|---|---|---|---|---|
| EXT | PIGSTY | 1.2.2 | 1817161514 | temporal_tables | - |
| RPM | PIGSTY | 1.2.2 | 1817161514 | temporal_tables_$v | - |
| DEB | PIGSTY | 1.2.2 | 1817161514 | postgresql-$v-temporal-tables | - |
构建
您可以使用 pig build 命令构建 temporal_tables 扩展的 RPM / DEB 包:
安装
您可以直接安装 temporal_tables 扩展包的预置二进制包,首先确保 PGDG 和 PIGSTY 仓库已经添加并启用:
使用 pig 或者是 apt/yum/dnf 安装扩展:
创建扩展:
用法
时态表(temporal table)是一种记录行有效时间段的表。系统时段(system period)是由系统自动维护的列(或列对),包含该行在数据库层面有效的时间范围。当你向这样的表中插入行时,系统会自动生成时段的起止值。当你更新或删除系统时段时态表中的行时,旧版本会自动归档到另一张表——即历史表(history table)。
更多用法可参考这篇优秀教程。
创建系统时段时态表
该扩展使用一个通用触发器函数来维护系统时段时态表的行为:
首先,创建一张表并添加系统时段列:
然后创建历史表:
历史表必须包含与原表同名、同类型的系统时段列。如果两张表都包含某列,则数据类型必须相同。
最后,创建触发器将其与历史表关联:
插入数据
向系统时段时态表插入数据与普通表类似:
sys_period 列的起始值表示该行何时变为当前版本,由 CURRENT_TIMESTAMP 自动生成。
更新数据
当用户更新行时,触发器会将旧行的副本插入历史表。如果单个事务内对同一行进行了多次更新,只会生成一条历史记录:
此时历史表包含之前的版本:
| name | department | salary | sys_period |
|---|---|---|---|
| Bernard Marx | Hatchery and Conditioning Centre | 10000 | [2006-08-08, 2007-02-27) |
更新冲突与时间调整
当多个事务更新同一行时,可能会发生更新冲突。当 adjust 参数设为 true 时,sys_period 的起始值会通过加上一个微小的时间增量(通常为 1 微秒)来避免冲突,否则会抛出 SQLSTATE 22000 错误。
删除数据
当用户删除数据时,触发器同样会将行添加到历史表:
高级用法
你可以为版本控制触发器设置自定义系统时间,这在从已记录时间戳的系统构建数据仓库时非常有用:
恢复默认行为:
如果在随后被中止的事务中执行,所有更改都会撤销。如果已提交,更改将持续到会话结束。
示例与技巧
使用继承创建历史表
历史表清理
历史表会持续增长。以下是几种清理策略:
- 定期删除历史表中的旧数据。
- 使用分区,并将旧分区从历史表中分离。
- 仅保留每行的最近 N 个版本。
- 当时态表中的对应行被删除时,同步清理历史记录。
- 按业务规则清理符合条件的行。
你也可以将历史表设置到另一个表空间,将其迁移到更廉价的存储上。
数据审计
你可以添加触发器来记录修改或删除当前行的用户: