Fowler的时间表达式的关系模式

16
马丁·福勒(Martin Fowler)在这里定义了一种优雅的对象模型,用于安排重复任务,并且可以很好地映射到OO代码。但是将其映射到关系型数据库模式以进行持久化却很棘手。
有人能否建议一个模式+SQL组合,以封装他描述的所有功能,特别是第11页上的图像。交集和并集相当明显——复杂性在于表示“时间表达式”,这些表达式采用可变参数并且必须以不同方式解释,然后将它们组合成一个“时间集”。
需要明确的是,在关系数据库中表示重复事件的概念有许多方法。我想听取大家对如何映射这个特定模型的意见。
一些可能的选项:
  • “元”表,用于定义参数的数量和使用情况。难看,但可能有效。但是,只有少数“时间表达式”形式是可行的,因此提供的极大灵活性可能太多。
  • 某种形式的表继承,由Postgres(和其他RBMS)支持。
将参数列表序列化并将结果存储在varchar()中不是解决方案,因为该方法会阻止集合查询 :)
2个回答

28
我担心这个答案会有很多参考资料和很少的实际代码,而且我最后一次涉及这个问题已经有一段时间了,但是...
我认为你想要混合的两种技术是'活动数据库''时间数据库'
第一个对于评估规则等非常有用,而第二个对于存储时间数据并在某个记录有效时进行评估非常有用。这两者都是相当大的研究领域,但你可以在普通的SQL中完成大部分时间相关的工作(前提是你的数据库具有良好的时间支持)。在SQL中进行活动部分比较困难,但是PostgreSQL至少有规则来稍微帮助解决这个问题。我不知道其他数据库情况如何,但是它们中的大多数都有规则/触发器/约束支持,可以转换为你所需要的内容。

活动数据库是可以使用规则对其存储的事实中的变化进行反应的数据库。这些规则用特定于实现的语言指定,但在日常讨论中,事件-条件-操作规则(ECA规则)很常见。要了解活动数据库系统的介绍,请阅读文章活动数据库管理系统宣言活动数据库系统。有关ECA规则的更多信息,请查看逻辑事件和ECA规则(页面顺序相反 o_0)和活动面向对象数据库系统中的事件

事件处理是规则处理的一种特殊情况,涉及如何处理复合事件并适时触发其动作。有关此内容的有趣阅读材料包括面向活动数据库的复合事件:语义、上下文和检测复合事件检测器的解剖学。还可以参考复杂事件处理网站以及事件流处理复杂事件处理维基百科文章。

时间数据库可以被视为能够理解时间的数据库,特别是两种具体的时间;有效时间和事务时间。记录的有效时间是该记录有效的时间段,而记录的事务时间是其存在于数据库中的时间。作为一个很好的实践介绍,我建议阅读Richard T. Snodgrass的书籍《在SQL中开发面向时间的数据库应用程序》。

否则,您可能想了解有关时间数据库的所有内容,可以阅读Springer数据库系统百科全书中的时间数据库条目,这是一份相当全面的文件(我建议从“时间数据库”条目开始阅读),但为了更快地入门,请查看时间数据库词汇表,它更容易浏览和阅读,以及Time Center网站,其中的出版物部分(或曾经)链接到该领域中最显着的出版物。

因此,现在您已经了解了所有这些,您会很快发现第11页上的图像可以表示为复合事件,并且可以作为这样的复合事件检测器的必需子集的实现进行检测/评估,其余部分可以表示为具有时间方面的表中的条目:)

Martin Fowler在他的随时间变化的事物的模式中自己解决了许多这方面的问题,总结了许多处理时间的模式。

最后,我可能会为时间信息创建数据库架构,并使用DB规则进行活动部分,或在应用程序中实现该部分(不过要小心)。如果您使用PostgreSQL,则规则机制在文档的规则系统部分中进行描述。

虽然需要阅读的内容很多,但如果您能彻底理解所有这些内容,您的专业净值可能会大幅提高 :)

此外,可供谷歌搜索的好词汇包括“时间数据库”、“活动数据库”、“ECA规则”。


我原本想给你一个恰当的答案,但是时间不够了,所以你只能得到我在必须停止时所拥有的一些脑海中的想法。希望你不介意。我认为这是一个好地方,可以让我存储这些链接以备将来参考 :) - Henrik Gustafsson
1
完全不是 - 只是'时间数据库'这个术语让我找到了一些新东西,包括这本书:http://www.cs.arizona.edu/people/rts/tdbbook.pdf - 即使它不完全符合我的需求,它仍然会很有趣 :) - majelbstoat
当然,我怎么可能忘记那个 :) 我会把它放在答案里,这样下一个人就不必读评论来找到它了。Snodgrass 在这个领域非常有权威性。 - Henrik Gustafsson

2

SQL是一种用于查询数据集的语言。它不容易支持特定领域逻辑操作的编码。换句话说,“要评估的规则”不是SQL中的数据类型。这是一个面向对象的概念,即数据和逻辑都是对象实例的组成部分。

因此,我会说在SQL范例内,你最多只能存储365行,对应于一年中的天数,并为每个相应的日期存储一个true/false值,以表示是否满足重复计划的条件。因此,您必须使用实现Fowler模型的OO逻辑进行计算,并存储结果的365行。

那么当您需要知道“今天(或任何给定日期)是否属于计划的一部分?”时,非常容易查找相应的行并检查true/false列。对于任何数据库来说,每年存储365行都是微不足道的。

这可能看起来像作弊,但正如我所说,SQL是关于数据集而不是逻辑的。


谢谢您的想法...我立刻看到的一个问题是无法重建用于生成日期集的规则。保存“每个星期一”将为您提供52(或53)个数据点,但加载这些点并不一定意味着“每个星期一”。 - majelbstoat
更好地建模时间。拥有一年中的日期表、星期几表、月份表等,所有这些都通过时间ID链接在一起。然后,您可以使用这些表上的选择来表示任何(基于日期的)规则。 - SquareCog
@Dmitriy:即使你这样做,你仍然有一个问题,那就是要连接哪些表,以及在WHERE子句中使用什么布尔表达式来组合这些条件。这不是SQL设计的解决问题。 - Bill Karwin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接