1

让我们看一个用户正在跟踪的traffic情景cities。流量每两个小时更新一次,我们必须保留以前的数据来绘制图表。所以我有一张traffic_stats看起来像这样的桌子 -

traffic_stats(id,city_id,user_id,traffic,created_at)

(给定流量是一个数字)

有一个 stats refresher daemon 获取唯一 city_id的 s,获取这些城市的当前交通统计信息,并将新条目添加到该表本身。守护程序使用此查询来获取city_id-

SELECT * FROM traffic_stats GROUP BY city_id

city_id并为同一个表中的每个添加新条目。每个新条目的user_id属性为 0,因为哪个用户订阅了城市并不重要。如果city_id在表中,它的 traffic_stats 会被刷新。

在前端,运行以下查询为用户获取数据 -

SELECT * FROM 
(SELECT * FROM traffic_stats WHERE user_id = #{session[:user_id]} ORDER BY created_at DESC)
as traffic_for_user_in_descending_order 
GROUP BY city_id

这为city_id 提供了单个最新条目。

这应该可以正常工作,除了如果 100 个用户正在跟踪 200 个独特的城市,那么traffic stats表中每两个小时就会有 200 个新条目。那是每天 2400 个条目,并且该表将继续增长。

现在,我可以有一个表,其中包含有关用户正在跟踪的城市的数据,以及另一个表,刷新守护程序添加条目。但我不确定这种方法是否有任何性能优势。

4

2 回答 2

2

最好创建一个单独的City表,这样您就可以从中查询不同的城市 ID,而不是在第一个 select 语句中扫描整个表。它也将使读取数据库更容易一些。如果您不想这样做,我建议您使用SELECT DISTINCT city_id FROM traffic_stats. 这样,您将检索到更少的信息。

在这种情况下,拥有一个表似乎是合理的,因为您使用信息的应用程序很简单。至于历史数据,最好创建一个单独的表来存储聚合信息。您可以修剪主表,选择并存储特定时间长度(天、周、月等)的平均值,然后通过基于用户 ID 的信息进行更多过滤。这将减少数据库磁盘使用和查询时间。

就我个人而言,我喜欢尽可能地打破常规。它确实可以进行更复杂的查询,但在我看来,它使使用和读取数据库中的信息变得更加容易。

于 2012-10-05T02:22:05.753 回答
2

您应该在单独的表中拆分city_idand ,例如. 然后类似的查询将为您提供守护程序的跟踪城市列表。如果您正确设置了索引、FK 等,则表的不断增长的大小应该无关紧要。user_iduser_citySELECT DISTINCT city_id from user_city

如果user_id始终为 0,traffic_stats那么WHERE user_id = #{session[:user_id]}您的查询如何工作?

使用所有可能索引的复杂查询很好。如果您每天/每周进行统计摘要,那么您还应该创建一个表来存储聚合数据,如 ralls23 建议的那样。这样您就不会读取 stats 表的每一行来生成输出/报告给用户。

于 2012-10-05T06:54:00.583 回答