0

我正在创建一个数据库来存储很多事件。它们会有很多,它们每个都有一个精确到秒的相关时间。例如,像这样:

Event
-----
Timestamp
ActionType (FK)
Source (FK)
Target (FK)

行动、来源和目标都在 6NF 中。我想保持Event表格标准化,但我能想到的所有方法都有问题。为了明确我对数据的期望,绝大多数(99.9%)事件将是唯一的,仅具有上述四个字段(因此我可以将整行用作 PK),但不能忽略少数例外.

  1. 使用代理键:如果我使用四字节整数,这是可能的,但似乎只是无缘无故地夸大表格。此外,我担心长时间使用数据库并耗尽密钥空间。

  2. 将计数列添加到事件:由于我希望计数较小,因此我可以使用较小的数据类型,这对数据库大小的影响较小,但在插入之前需要更新插入或汇集数据库外部的数据。其中任何一个都会增加复杂性并影响我对数据库软件的选择(我正在考虑使用 Postgres,它会进行 upserts,但并不乐意。)

  3. 将事件分成小组:例如,同一秒内的所有事件都可能是 a 的一部分,Bundle其中可能有一个代理键用于组,另一个用于其中的每个事件。这为数据库增加了另一层抽象和大小。如果其他重复的事件变得普遍,那将是一个好主意,但否则似乎有点矫枉过正。

虽然所有这些都是可行的,但它们感觉不适合我的数据。我正在考虑只做一个典型的雪花而不是在主表上强制执行唯一性约束,但是在阅读了这样Event的PerformanceDBA 答案后,我认为也许有更好的方法。

那么,保持具有少量重复事件的时间序列数据归一化的正确方法是什么?

编辑:澄清 - 数据来源是日志,主要是平面文件,但也有一些在各种数据库中。该数据库的一个目标是统一它们。没有一个来源的时间分辨率比第二个更精确。这些数据将用于诸如“有多少不同的来源在时间间隔内对目标执行操作?”之类的问题。其中间隔不会少于一个小时。

4

1 回答 1

4

最简单的答案似乎是

  • 以更高的精度存储时间戳,或
  • 如果 INSERT 由于重复键而失败,则将时间戳存储到第二个并重试(使用稍晚的时间戳)。

您提到的三个想法都与规范化无关。这些是关于存储什么的决定;在概念级别,您在决定存储什么后进行规范化。行的含义(因此,每列的含义)很重要;这些含义构成了表的谓词。谓词使您可以从较旧的真实事实中得出新的真实事实。

使用整数作为代理键,您不太可能耗尽键空间。但是您仍然必须声明自然键,因此在这种情况下,代理对您没有任何用处。

如果对事物进行计数有意义,则添加“计数”列是有意义的;否则它不会。看看这两个例子。

Timestamp            ActionType  Source  Target
--
2013-02-02 08:00:01  Wibble      SysA    SysB
2013-02-02 08:00:02  Wibble      SysA    SysB

Timestamp            ActionType  Source  Target  Count
--
2013-02-02 08:00:01  Wibble      SysA    SysB    2

这里的含义有什么区别?“时间戳”的含义尤为重要。规范化是基于语义的;您需要做什么取决于数据的含义,而不是列的名称。

如果事件组在您的系统中有意义,则将事件分成小组可能有意义(例如添加“计数”列可能有意义)。

于 2013-02-19T12:29:59.840 回答