6

我的直觉告诉我,开始时间和结束时间通常比开始时间和持续时间要好,但我想知道不同方法是否有一些具体的优点或缺点。

我看到的 strttime 和 endtime 的优点是,如果您想在某个时间段内调用所有活动,则不必查看该时间段之外的内容。

(这是针对在初始输入后不太可能发生太大变化并且与特定时间相关联的事件,如果这会有所不同的话)

4

3 回答 3

13

我不认为这是一种偏好或个人选择。计算机科学是一门科学,我们是编程机器,而不是敏感的孩子。

重新发明轮子

整个行业的巨头都撰写了有关关系数据库中的时间数据主题的整本书。Codd 已经去世了,但他的同事和合著者 CJ Date 和最近的 H Darwen 在The Third Manifesto中继续推进和完善关系模型的工作。关于该主题的开创性著作是CJ Date、Hugh Darwen 和 Nikos A Lorentzos 所著的 Temporal Data & the Relational Model

有很多人发表关于 CS 科目的意见和个人选择,就好像他们在选择冰淇淋一样。这是由于没有接受过任何正式培训,因此将他们的 CS 任务视为地球上唯一遇到该问题并找到解决方案的人。基本上,他们从头开始重新发明轮子,就好像不存在其他轮子一样。阅读技术资料(不包括 Wikipedia 和 MS 出版物)可以节省大量时间和精力。

购买现代车轮

时间数据一直是一个问题,成千上万的数据建模者遵循 RM 并试图实施良好的解决方案。其中一些是好的,而另一些则不是。但现在我们有巨头的工作,经过认真研究,并提供了解决方案和规定的治疗方法。和以前一样,这些最终将在 SQL 标准中实现。PostgreSQL 已经有几个必需的函数(作者是 TTM 的一部分)。

因此,我们可以采用这些解决方案和处方,它们将 (a) 面向未来并且 (b) 可靠(与目前存在的数千个不太好的时间数据库不同),而不是依赖于个人意见或流行在一些网站上投票。不用说,代码也会容易得多。

购买前检查

如果您进行一些谷歌搜索,请注意也有非常糟糕的“书籍”可用。这些是在 MS 和 Oracle 的旗帜下由在冰淇淋店度过一生的博士出版的。因为他们没有阅读和理解教科书,他们对问题的理解很肤浅,并且发明了相当不正确的“解决方案”。然后他们继续提供大量解决方案,不是针对时间数据,而是针对其“解决方案”中固有的大量问题。您将被锁定在已识别且唯一的问题中;并实现触发器和各种不必要的代码。任何免费提供的东西都值得您为此付出的代价。

时间数据

因此,对于您的问题范围,我将尝试简化时间问题,并解释教科书的指导。简单的规则,同时考虑规范化和时间要求,以及您没有预见到的使用。

  1. 首先,对任何类型的 Temporal 列使用正确的数据类型。这意味着 DATETIME 或 SMALLDATETIME,具体取决于您需要的分辨率和范围。如果只需要 DATE 或 TIME 部分,您可以使用它。这允许您直接在 WHERE 子句中使用 SQL 函数执行日期和时间算术。

  2. 其次,确保为列和变量使用非常清晰的名称。

  3. 有三种类型的时态数据。这一切都是为了正确分类,以便治疗(计划内和计划外)很容易(这就是为什么你的问题是一个好问题,为什么我会提供完整的解释)。优点是使用内联日期/时间函数的 SQL 更简单(您不需要计划中的 Temporal SQL 函数)。始终存储:

即时为 SMALL/DATETIME,例如。更新Dtm

间隔为 INTEGER,明确标识列名中的 Unit,例如。IntervalSec或者NumDays

  • 有一些技术人员认为,无论使用什么组件,间隔都应该存储在 DATETIME 中,例如自 1900 年 1 月 1 日午夜以来的秒数或月数等。这很好,但需要更笨拙(不复杂)的代码在初始存储中以及提取时。

  • 无论您选择什么,都要保持一致。

期间或持续时间。这被定义为两个单独的瞬间之间的时间段。存储取决于期间是合还是不合。

  • 对于合并期间如您的事件要求:使用一个 SMALL/DATETIME EventDateTime;Period 的结尾可以从下一行的 Period 的开头推导出来,EndDateTime不应存储。

  • 对于不相干的Periods,中间有间隔,是的,您需要 2 x SMALL/DATETIMEs,例如。一个RentedFrom和一个RentedTo。如果在同一行。

  • 跨行的 Period 或 Duration 只需要将结束 Instant 存储在其他行中。ExerciseStart 是Event.DateTimeX1 Event行的,ExerciseEnd 是Event.DateTimeX9 Event行的。

因此,存储为间隔的 Period 或 Duration 根本不正确,不受意见。

数据复制

另外,在规范化数据库中,即。whereEndDateTime不存储(除非不相交,如上所述),存储可以派生的数据将在没有的地方引入更新异常。

  • 有了一个EndDateTime,你在一个地方就有了一个真相的版本;与重复数据一样,您在另一列中有第二个版本的事实:

  • 打破 1NF

  • 这两个事实需要以事务方式一起维护(更新),并且存在不同步的风险

  • 由于事实的两个版本,不同的查询可能会产生不同的结果

  • 通过保持科学很容易避免所有这些。返回(单个查询速度的微不足道的增加)不值得破坏数据的完整性。

回应评论

您能否稍微扩展一下 conjunct 和 disjunct 之间的实际区别以及这些概念对数据库设计的直接实际影响?(据我了解,我的数据库中的练习和临时基础是不相交的,因为它们是由空格分隔的不同事件。而基础本身是结合的,因为总是有一个值)

不完全的。在您的数据库中(据我所知):

  • 所有事件都是Instants,而不是连接或分离的时期

  • 例外是Exercise 和TempBasal,它们存储了结束瞬间,因此它们有句点,句点之间有空格;因此它们是分离的。

  • 我认为您想确定更多的持续时间,例如 ActiveInsulinPeriod 和 ActiveCarbPeriod 等,但到目前为止,它们只有一个导致事件的事件(即时)。

  • 我不认为你有任何联合时期(很可能有,但我很难确定任何时期。我收回我所说的(当它们是读数时,它们看起来是联合的,但我们已经取得了进展)。

  • 有关我们可以使用实际效果的联合周期的简单示例,请参阅此时间序列问题。文本和代码可能很有价值,所以我已经链接了 Q/A,但我特别希望你看看数据模型。忽略这三个实现选项,它们与此上下文无关。

  • 该数据库中的每个 Period 都是Conjunct。产品始终处于某种状态。任何 Period 的 End-DateTime 都是Product下一行的 Start-DateTime。

于 2011-01-31T06:29:11.867 回答
4

这完全取决于您想对数据做什么。正如您所说,如果您存储它,您可以按结束时间过滤。另一方面,如果您想查找“所有事件持续时间超过一个小时”,那么持续时间将是最有用的。

当然,如有必要,您可以随时存储两者。

重要的是:你知道你将如何使用这些数据吗?

编辑:只是为了增加一点肉,根据您使用的数据库,您可能希望考虑使用视图:仅存储(例如)开始时间和持续时间,但有一个公开开始时间、持续时间的视图计算结束时间。如果您需要查询所有三列(无论是一起还是单独),您需要检查您的数据库对索引视图列的支持。这具有方便和清晰的好处,但没有数据冗余的缺点(必须保持“备用”列与其他两个列同步)。另一方面,它更复杂,需要您的数据库提供更多支持。

于 2011-01-28T22:30:05.540 回答
1

结束 - 开始 = 持续时间。
有人可能会争辩说您甚至可以使用 End 和 Duration,因此任何组合都没有区别。

除了你需要的琐碎the column included to filter on it,所以包括

  • 持续时间:如果您需要按执行时间进行过滤
  • start + end:如果您需要捕获在一个时间范围开始和结束的事件
于 2011-01-28T22:40:13.753 回答