简化示例:两个表 - 人和时间。目标是跟踪一个人走过门口的所有时间。
一个人每天可以在时间表中有0到50个条目。
跟踪这些记录的正确和最有效的方法是什么?是吗
times table
-----------
person_id
timestamp
我担心这张桌子可以很快地获得超过一百万条记录。插入和检索时间至关重要。
另外:显然非标准化但是做一个更好的主意
times table
-----------
person_id
serialized_timestamps_for_the_day
date
我们需要访问此人的每个时间戳,但仅查询日期或人员ID的记录。
答案 0 :(得分:1)
考虑一下我们在这里谈论什么。仅考虑原始数据(event_time, user_id)
,这将是每1M行(4 + 4) * 1M ~ 8MB
。让我们尝试在DB中粗略估计一下。
一个整数4个字节,时间戳4个字节;行标题,比方说18个字节 - 这会将行大小的第一个估计带到4 + 4 + 18 = 26 bytes
。使用页面填充因子约为0.7; ==>
26 / 0.7 ~ 37
个字节。
因此,对于1M行,大约37 MB。您需要(user_id, event_time)
上的索引,所以我们只需将原始内容翻倍为37 * 2 = 74 MB
。
这使得非常粗略,无法估计的估计值为每1M行74MB。
因此,要始终将其保留在内存中,此表的每1M行需要0.074 GB。
要获得更好的估算,只需创建一个表,添加索引并用几百万行填充它。
考虑到预期的数据量,即使在笔记本电脑上也可以轻松测试10M行 - 测试总是比较推测。
P.S。您的选项2 不看起来“明显更好的主意”我也是。
答案 1 :(得分:1)
第二种解决方案存在一些问题:
serialized_timestamps_for_the_day
不能被视为atomic并且会违反1NF,从而导致bunch of problems。date
可以从serialized_timestamps_for_the_day
的内容中推断出来,您的应用程序代码需要确保它们永远不会变得“失去同步”,这容易受到错误的影响。 2 因此请选择第一个解决方案。如果properly indexed,现代硬件上的现代数据库可以处理的不仅仅是“超过一百万条记录”。在这个具体案例中:
1 即使您不查询单个时间戳,仍需要逐个将它们写入数据库。如果您有序列化字段,则首先需要读取整个字段以仅附加一个值,然后将整个结果写回数据库,这可能会很快成为性能问题。还有其他问题,如上面的链接所述。
2 作为一般规则,不能存储的内容,除非有良好的表现理由这样做,我不知道看到这里的任何内容。
答案 2 :(得分:0)