【问题标题】:Hot Topics in 30 days range30天范围内的热门话题
【发布时间】:2015-07-23 16:02:03
【问题描述】:

我的数据库表中有超过 10k 个主题,我计算会话库中每个主题的页面浏览量,并且只存储一个视图/每个主题/每个用户(会话时间 24 小时)。

ID-----Topic----------------Views
1------Love------------------400
2------Friends---------------203
3------Birthday--------------360

现在我想获取最近 30 天的热门话题,意思是我想根据最近 30 天的页面浏览量来获取热门话题。我只需要一点方向,关于如何实现这一点。谢谢

【问题讨论】:

  • 您想在 SQL 或 C# 中执行此操作吗?此外,我们需要知道您的表格包含的内容(特别是日期戳的方式)以提供任何帮助。
  • 我想你有另一个表格,上面有视图的日期和一个指向主题的 fk,是这样吗?
  • 感谢快速回复。目前我有主题发布日期(smalldatetime),我认为 C# 方式会很好。你认为呢?而且我还可以用 FK 制作新表。
  • 您是否将各个视图事件存储在自己的表中?没有它,如果您只是更新标题行上的计数器,则很难按时间范围按视图过滤。
  • @willaien:是的,目前我正在更新主题表中的视图。

标签: c# sql asp.net asp.net-mvc


【解决方案1】:

如果您想真正适应最近的视图,您将需要分成 Topic 表和 TopicView 表。使用当前的表格结构,不知道视图的最新程度 - 因此,如果您在一年中的第 10 周有一个话题高峰期,它可能会在很长一段时间内保持在您的热门话题列表中的第一名(如'Views' 列是一直累积的)。

CREATE TABLE Topic (
    [Id] INT NOT NULL IDENTITY(1,1)
    [Topic] VARCHAR(255) NOT NULL
)

CREATE TABLE TopicView (
    [ViewId] INT NOT NULL IDENTITY(1,1),
    [TopicId] INT NOT NULL,
    [User] VARCHAR(255) NOT NULL,
    [ViewDate] DATETIME NOT NULL
)

现在,您可以在用户每次点击页面时检查您是否已经为他们记录了“TopicView”。当您想查看热门话题时,您可以执行:

DECLARE @maxResults INT = 100  --the maximum number of results we will show
DECLARE @hotTopicViewDays INT = 30 --how recent we want to see hot topic activity
DECLARE @hotTopicViewLimit INT = 300 --what amount of views we consider hot


SELECT TOP (@maxResults)
    T.[Id],
    T.[Topic],
    COUNT(TV.[ViewID]) [Views]
FROM [Topic] T
    JOIN [TopicView] TV
    ON T.[Id] = TV.[TopicId]
WHERE TV.ViewDate >= DATEADD(DAY, -(@hotTopicViewDays), GETDATE())
GROUP BY T.[Id],
    T.[Topic]
HAVING COUNT(TV.[ViewId]) >= @hotTopicViewLimit

这是相当可扩展的,并且允许您进行配置:

  1. 您希望使用@maxResults 返回多少个结果
  2. 使用@hotTopicViewDays 需要如何将最近的浏览量纳入“热门话题”活动
  3. 使用@hotTopicViewLimit 考虑“热门”主题需要多少活动

如果有任何问题或是否有人发现这种方法存在问题,请告诉我。

【讨论】:

  • 我完全同意这是查询观看次数最多的主题的真正方法,但是,OP 已经有 10,000 条记录,他永远不会知道正确的日期范围。
  • @Chris:我现在就实现它,很快就会发布结果。非常感谢您的回复。
  • 我应该指出,TopicView 表可以非常大,这取决于视图的数量。您应该牢记这一点并在必要时包含索引,或者更改表示以将所有每日视图分组到一个元组中
  • @Troveldom:是的,我知道随着时间的推移它会非常大,但我每 24 小时为每个用户添加 1 次视图。根据谷歌分析,该网站目前每天有超过 20k 的独立访问者。你能解释一下关于一个元组的更多信息吗?谢谢
  • 您可以更改 TupleView 的定义,删除用户并添加一个整数,表示该日期的总浏览量。它与您以前的类似,但每天都有一个条目。您将记录更少的数据(例如没有用户跟踪,没有时间访问信息),但我认为您应该记住这一点,以防随着时间的推移出现性能问题。
【解决方案2】:

您已经将视图存储在数据库中,这很好。您还需要存储创建主题的日期。

如果你已经这样做了,你可以写一个查询这个(我不知道你的列名等):

SELECT *
FROM Topics t
WHERE t.DateAdded >= dateadd(day, -30, getdate())
ORDER BY t.Views DESC

它返回最近 30 天内创建的所有主题,最先查看的主题。

您不想将所有一万条记录加载到内存中,因此请确保实现分页。

【讨论】:

  • 您可以使用 GROUP BY 子句选择 count(*)、topic.name 并获取所需的确切数据。
  • 可能值得添加一个可配置的Views > x 约束,因为他说他只想要“热门”主题。然后他就可以设置“热”的含义。
  • 或其他选项 - TOP (@postLimit)SELECT 的补充
  • @ChrisSchubert 是的。我不太确定什么是“最热门”。我怀疑像 Reddit 这样的网站会根据视图交互(如 cmets 和链接点击)来确定热门话题。写一个 SO 答案可能相当复杂。
  • @Petrichor:感谢您的回复,但我将首先实施 Chris Schubert 解决方案。干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 2015-09-10
  • 1970-01-01
  • 2017-03-11
  • 2017-10-07
相关资源
最近更新 更多