双时态数据管理和外键可能非常棘手。对于双时态表之间的主从关系,需要在主表中引入一个“人工密钥”,该“人工密钥”对于对象的不同时态或历史版本来说不是唯一的,而是相同的。该密钥是从卫星引用的。连接两个表时,必须为连接提供双时态上下文 (T_TIME, V_TIME),其中 T_TIME 是事务时间,V_TIME 是有效时间。加入将类似于以下内容:
SELECT m.*, s.*
FROM master m
LEFT JOIN satellite s
ON m.key = s.master_key
AND <V_TIME> between s.valid_from and s.valid_to
AND <T_TIME> between s.t_from and s.t_to
WHERE <V_TIME> between m.valid_from and m.valid_to
AND <T_TIME> between m.t_from and m.t_to
在此查询中,有效期限由列给出,valid_from
事务valid_to
周期由列给出,主表t_from
和t_to
卫星表都给出。主库中的人工密钥由列给出,m.key
对此密钥的引用由给出s.master_key
。左外连接也用于检索主表的那些在卫星表中没有对应条目的条目。
正如您在上面提到的,此连接条件可能很慢。另一方面,这种布局可能更节省空间,因为如果仅更新主数据(在可交易中)或仅卫星数据(在表 trade_support 中),则只需在相应表中输入新条目。当对所有数据使用一个表时,需要为组合表中的所有列创建一个新条目。此外,您最终会得到一个包含许多空值的表。
因此,您提出的问题归结为空间要求和简洁代码之间的权衡。使用单表解决方案牺牲的空间量取决于附属表的列数。我可能会选择单表解决方案,因为它更容易理解。
如果您有机会转换数据库技术,面向文档的数据库可能更有意义。我已经编写了一个基于 mongodb 的双时态 scala 层原型,可在此处获得:
https://github.com/1123/bitemporaldb
这将允许您在没有连接的情况下工作,并使用更灵活的交易数据结构。