【发布时间】: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 是指示位置的浮点数。该表的一个明显问题是字段gender、age 和name 将针对每个时间戳重复多次。在阅读了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_id 和time 作为PK 来尝试符合第六范式(6NF),正如答案中所建议的那样上面的链接——这可能会带来更高的性能。不过严格来说,6NF requires only one other attribute for each PK
,但就我而言,我有两个(xloc 和 yloc)。最近的 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),
);
在这种情况下,客户端应该知道该数组按顺序表示x 和y 位置,但目前这不是问题。从技术上讲,该表现在每个 PK 只有一个属性,但我对它的性能更感兴趣。一般来说,我是 Postgres 和 DB 的新手。就性能而言,使用数组类型会更好吗?
数据和用例:每个用户的位置时间序列可能长达数千万次测量,并且间隔不同。 read ops 将超过 write ops —— 事实上,现在我的数据是静态的,生成的数据库将被一个小团队用于统计分析,至少现在是这样。 我的查询将是例如男性用户测量,或30岁以下用户周日测量。
您会推荐哪些替代设计?
【问题讨论】:
-
@a_horse_with_no_name relational-database 肯定是相关的,因为“6NF”在此之外没有任何意义。
标签: sql postgresql database-design time-series