我正在构建一个存储自定义数据集的Rails应用程序。 更具体地说,我正在存储排行榜的存档。 每个排行榜都有一组排行榜条目,这些条目可以具有自定义字段(换句话说,并非所有排行榜都具有相同的格式)。
快速示例:
Leaderboard 1 (Fields)
-------------
7_day_exponential_moving_average
total_count
Leaderboard 2 (Fields)
-------------
10_day_exponential_moving_average
total_count
现在,我正在将所有排行榜条目序列化到排行榜中名为"data"的字段中。 结果是我对超过 30,000 个对象执行计算,并将结果存储在单个字段中。
我开始发现异步执行计算时存在一个缺陷(我需要等待所有计算完成,监视它们是否完成,然后存储所有数据),并且似乎创建一个名为 LeaderboardEntry 的单独模型会更有意义。 我想知道的是存储和查询 30,000 个不同对象与将所有 30,000 个条目存储在单个字段中的性能影响,就像我已经做的那样。
我认为一个请求和一个响应会表现得更好。 (即
SELECT serialized_data FROM leaderboards WHERE leaderboard_id=123 <-- 1 row with a very large field
与
SELECT * FROM leaderboard_entries WHERE leaderboard_id=123 <-- 30,000 rows with small sets of data
我将其存储在序列化字段中的假设是否正确? 或者单独存储条目没什么大不了的? 我在这里的另一个想法是:使用像MongoDB这样的nosql解决方案可能会更有效,然后我可以按leaderboard_entry字段排序并将结果限制为少量(一次50个结果)。
最终,我每天将生成超过 100 万个排行榜条目(20+ 排行榜),我只是想找出最有效的存储方式。
谢谢!
一个大的序列化字段肯定比一堆小条目更有效地存储和检索(Postgres 会将整个内容存储为 CLOB)。也就是说,这几乎可以肯定是一个过早的优化。规范化数据的优势是显著的 - 您可以使用 select where field > xxx and field < yyy
分段单步执行 30k 行查询,这将使您的访问时间非常快。Postgres可以非常有效地对许多小物体进行操作。如果你的数据只是半结构化的,看看"hstore"和JSON数据类型,postgres可以通过查询来检查它们。
这似乎不是一个足够大的问题来考虑数据库的切换 - MongoDB在这里不会有任何直接的优势。大多数情况下,症结在于如何设计数据访问查询。例如,使用良好的索引选择部分数据集总是比执行大型开放式select *
更快。
查看您预期执行的查询类型的"解释计划",并相应地进行调整。如果您对不同类型查询的成本感兴趣,那么将一堆测试数据加载到测试数据库中,然后查看Postgres提出的查询计划通常很有用。不同查询计划的成本相对数量可以非常有效地指导您上线时的痛点。