【问题标题】:Database design for timeseries in SQLSQL中时间序列的数据库设计
【发布时间】:2019-10-01 18:25:51
【问题描述】:

我有带时间戳的地理位置数据和一些其他关于用户的信息,我正在寻找有关设计数据库的建议。我猜一个幼稚的设计是:

CREATE TABLE user(
    user_id INT NOT NULL,
    name VARCHAR(128) NOT NULL,
    gender VARCHAR(128) NOT NULL,
    age INT NOT NULL,
    time TIMESTAMPTZ NOT NULL,
    xloc FLOAT(4) NOT NULL,
    yloc FLOAT(4) NOT NULL,
    PRIMARY KEY(user_id),
);

这里的xloc, yloc 是指示位置的浮点数。该表的一个明显问题是字段genderagename 将针对每个时间戳重复多次。在阅读了Storing time-series data, relational or non? 中非常全面的接受答案后,我决定更好的解决方案是将地理位置数据放在单独的表中,即有两个表:

CREATE TABLE geodata(
    user_id INT NOT NULL,
    time TIMESTAMPTZ NOT NULL,
    xloc FLOAT(4) NOT NULL,
    yloc FLOAT(4) NOT NULL,
    PRIMARY KEY (user_id, time),
);

CREATE TABLE user(
    user_id INT NOT NULL,
    name VARCHAR(128) NOT NULL,
    gender VARCHAR(128) NOT NULL,
    age INT NOT NULL,
    PRIMARY KEY (user_id),
);

请注意,在geodata 表中,我同时使用user_idtime 作为PK 来尝试符合第六范式(6NF),正如答案中所建议的那样上面的链接——这可能会带来更高的性能。不过严格来说,6NF requires only one other attribute for each PK ,但就我而言,我有两个(xlocyloc)。最近的 PostgreSQL 版本允许使用array types,因此另一种选择是:

CREATE TABLE geodata(
    user_id INT NOT NULL,
    time TIMESTAMPTZ NOT NULL,
    loc FLOAT(4) ARRAY[2] NOT NULL,
    PRIMARY KEY (user_id, time),
);

在这种情况下,客户端应该知道该数组按顺序表示xy 位置,但目前这不是问题。从技术上讲,该表现在每个 PK 只有一个属性,但我对它的性能更感兴趣。一般来说,我是 Postgres 和 DB 的新手。就性能而言,使用数组类型会更好吗?

数据和用例:每个用户的位置时间序列可能长达数千万次测量,并且间隔不同。 read ops 将超过 write ops —— 事实上,现在我的数据是静态的,生成的数据库将被一个小团队用于统计分析,至少现在是这样。 我的查询将是例如男性用户测量,或30岁以下用户周日测量

您会推荐哪些替代设计?

【问题讨论】:

  • @a_horse_with_no_name relational-database 肯定是相关的,因为“6NF”在此之外没有任何意义。

标签: sql postgresql database-design time-series


【解决方案1】:

时间序列和时间数据本身并不使用 6NF。 (加快该链接的速度。)需要的是要记录原子更改的 CK 和相关数据。 6NF 只是经常需要,但它本身并不是目标。非 CK 数据可以是多列——您想记录对位置的更改,而不是对坐标的更改。 (类似地,当您想知道整数是否改变时,没有人会因为您没有针对每个 CK 和数字的表而感到不安。)您可以将其视为具有 CK 和一个元组或记录的 6NF 表的转换值列。

所以这里有 CK & X & Y 的设计是可以的——只要您不需要知道特定坐标值何时发生变化。

“总的来说,我是 Postgres 和 DB 的新手。”然后忘记“性能”,直到您了解足够多的知识以了解它的含义。进行简单的设计。接下来了解约束和索引。

关于时间数据(包括 6NF)每个人都应该阅读 Date、Darwen 和 Lorentzos。避免使用 Snodgrass。

PS PK 与关系模型理论无关,CK 很重要,PK 只是您称之为 PK 的一些 CK。 PS 请注意,SQL PK 或多或少是一个超级键而不是 CK;它可以包含一个更小的 UNIQUE/superkey。

PS 6NF 意味着不满足任何重要的 JD。它暗示“主键,最多一个其他属性”,但后者不是 6NF 的定义。另请注意,该条件本身并不完全意味着一个 CK。可能还有更多。

PS Wikipedia 不是关系模型信息的可靠来源。例如There's no one "1NF" & 它们与导致 6NF 的 NF 的归一化正交。例如,PK 无关紧要。例如,对较高 NF 的标准化不是通过通过较低 NF 来完成的。 (此外,它可以排除良好的目标-NF 设计。)例如,DKNF 不属于通向 6NF 的 NF 中的那个页面。比如它对6NF的定义是错误的。

【讨论】:

  • 非常感谢您的意见。我同意首先让它发挥作用,然后专注于性能是正确的方法。但在我的情况下,性能对于进行查询和分析等的团队来说非常重要。现在我们有数十万个测量文件放在一个文件夹中,我们只是直接批量加载文件进行分析等。团队如果它慢得多,就不会使用数据库。
  • 所以如果我理解正确,我应该使用 CK & (X,Y) 而不是 CK & X & Y(即 X,Y 的数组类型而不是单独的列),对吧?每个位置测量都是一个原子(x,y),而不是xy 是独立的事物。我绝对不会只查询xy 列。
  • 我说使用 CK 列和 X 和 Y 列。我认为这从“CK & X & Y 很好——只要你不需要知道特定坐标的时间值改变”。我解释说没有 reasonit is generally ill-advised 的数组。重新性能见我的下一条评论。 PS显然需要您分解为 2 个表,而与您的应用程序无关。是时候阅读有关信息建模、关系模型和数据库设计的教科书了。然后针对您的 DBMS 进行优化。
  • 我目前的一般评论是“更好”/“最好”等:除非你定义它,否则工程中没有“更好”/“最好”之类的东西。同样不幸的是,所有合理的实际定义都需要大量的经验,以及与对细节的混乱敏感度相互作用的大量因素。进行简单的设计。当您通过测量证明您可以想到的设计和所有替代方案都存在问题时(无论当时意味着什么),然后提出一个非常具体的问题。这也应该定义“更好”/“最好”。 meta.stackexchange.com/q/204461
  • “CK & X & Y 很好——只要你不需要知道特定坐标值何时改变”——这是我不明白的部分,不应该不是相反吗?如果 xy 有单独的列,我不是告诉数据库这些是独立的属性吗?
猜你喜欢
  • 2019-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-30
  • 2012-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多