TimescaleDB数据模型(翻译整理)

2022-03-25 00:00:00 序列 数据 模型 时间 指标

内容概览

  1. 宽数据模型(宽表)。

  2. 窄数据模型(窄表)。


定义

宽表:从字面意义上讲就是字段比较多的数据库表。通常是指业务主题相关的指标、维度、属性关联在一起的一张数据库表。由于把不同的内容都放在同一张表存储,宽表已经不符合三范式的模型设计规范,随之带来的主要坏处就是数据的大量冗余,与之相对应的好处就是查询性能的提高与便捷。这种宽表的设计广泛应用于数据挖掘模型训练前的数据准备,通过把相关字段放在同一张表中,可以大大提高数据挖掘模型训练过程中迭代计算时的效率问题。(一句话,空间换时间,便于训练迭代、减少表关联数量,修改少量数据时不需要该多张表)


窄表:严格按照数据库设计三范式。尽量减少数据冗余,但是缺点是修改一个数据可能需要修改多张表


宽数据模型(宽表)

TimescaleDB 很容易支持宽表模型。在此模型中,跨多个指标的查询更容易,因为它们不需要 JOIN。此外,摄取速度更快,因为只为多个指标编写了一个时间戳。


一个典型的宽表模型将匹配一个典型的数据流,其中在给定的时间戳收集多个指标:

timestampdevice_idcpu_1m_avgfree_memtemperaturelocation_iddev_type
2017-01-01 01:02:00abc12380500MB7242field
2017-01-01 01:02:23def45690400MB6442roof
2017-01-01 01:02:30ghi7891200MB5677roof
2017-01-01 01:03:12abc12380500MB7242field
2017-01-01 01:03:35def45695350MB6442roof
2017-01-01 01:03:42ghi789100100MB5677roof

在这里,每一行都是一个新读数,在给定时间具有一组测量值和元数据。这使我们能够保留数据中的关系,并提出比以前更有趣或探索性的问题。

当然,这不是一种新格式:它是关系数据库中常见的格式。

加入关系数据

TimescaleDB 的数据模型与关系型数据库还有一个相似之处:它支持 JOIN。具体来说,可以将其他元数据存储在辅助表中,然后在查询时使用该数据。

在我们的示例中,可以有一个单独的位置表,映射location_id到该位置的其他元数据。例如:

location_idnamelatitudelongitudezip_coderegion
42Grand Central Terminal40.7527° N73.9772° W10017NYC
77Lobby 742.3593° N71.0935° W02139Massachusetts

然后在查询时,通过连接我们的两个表,可以提出以下问题:free_mem我们的设备在zip_code10017 中的平均值是多少?

如果没有连接,则需要对其数据进行非规范化并将所有元数据存储在每个测量行中。这会造成数据膨胀,并使数据管理更加困难。

通过联接,可以独立存储元数据,并更轻松地更新映射。

例如,如果我们想更新location_id77 的“区域”(e.g., from "Massachusetts" to "Boston"),我们可以进行此更改,而无需返回并覆盖历史数据。

窄数据模型(窄表)


大多数时间序列数据库会以下列方式表示这些数据:


将每个指标表示为一个单独的实体(例如,将cpu_1m_avg 和表示free_mem为两个不同的事物)为该指标存储一系列“时间”、“值”对将元数据值表示为与该指标/标签集组合关联的“标签集”在这个模型中,每个度量/标签集组合都被认为是一个单独的“时间序列”,其中包含一系列时间/值对。


使用我们上面的示例,这种方法将产生 9 个不同的“时间序列”,每个“时间序列”都由一组的标签定义。

1. {name:  cpu_1m_avg,  device_id: abc123,  location_id: 335,  dev_type: field}
2. {name: cpu_1m_avg, device_id: def456, location_id: 335, dev_type: roof}
3. {name: cpu_1m_avg, device_id: ghi789, location_id: 77, dev_type: roof}
4. {name: free_mem, device_id: abc123, location_id: 335, dev_type: field}
5. {name: free_mem, device_id: def456, location_id: 335, dev_type: roof}
6. {name: free_mem, device_id: ghi789, location_id: 77, dev_type: roof}
7. {name: temperature, device_id: abc123, location_id: 335, dev_type: field}
8. {name: temperature, device_id: def456, location_id: 335, dev_type: roof}
9. {name: temperature, device_id: ghi789, location_id: 77, dev_type: roof}

这种时间序列的数量与每个标签的基数的叉积成比例,即(#names)×(#device ids)× (#location ids)× (device *)。随着基数的增加,一些时间序列数据库会遇到困难,终限制了您可以存储在单个数据库中的设备类型和设备的数量。

TimescaleDB 支持窄模型,并且不会受到与其他时间序列数据库相同的基数限制。如果您独立收集每个指标,那么一个狭窄的模型是有意义的。它允许您通过添加新标签随时添加新指标,而无需正式更改架构。

但是,如果您要收集许多具有相同时间戳的指标,则窄模型的性能会降低,因为它需要为每个指标编写时间戳。这终会导致更高的存储和摄取要求。此外,关联不同指标的查询也更加复杂,因为您想要关联的每个附加指标都需要另一个 JOIN。如果您通常一起查询多个指标,那么将它们存储在宽表格式中既更快又更容易。

来源 https://mp.weixin.qq.com/s/mxIqa4o8JjPHqTMi9nAS9w

相关文章