Database design 如何跟踪用户在X天内每天访问站点的情况?

Database design 如何跟踪用户在X天内每天访问站点的情况?,database-design,methodology,Database Design,Methodology,堆栈溢出上有一个新的标记。“徽章”颁发给每天访问网站的用户,为期30天。如何实现这样的功能?您如何以最简单的方式跟踪用户每天访问站点X天的情况 我想有两个字段——一个用于最后一次登录的时间戳,另一个用于计算用户连续访问站点的天数。逻辑是首先将计数器设置为1,并存储登录时间。在下一次登录时,检查自上次登录后是否没有超过一天,并增加计数器,或将其设置回1。然后将时间戳字段更新为当前日期 您能做得更简单吗?用时间戳跟踪数据库中的每次访问(您可能已经这样做了)。然后创建一条sql语句并按天对结果进行分组

堆栈溢出上有一个新的标记。“徽章”颁发给每天访问网站的用户,为期30天。如何实现这样的功能?您如何以最简单的方式跟踪用户每天访问站点X天的情况

我想有两个字段——一个用于最后一次登录的时间戳,另一个用于计算用户连续访问站点的天数。逻辑是首先将计数器设置为1,并存储登录时间。在下一次登录时,检查自上次登录后是否没有超过一天,并增加计数器,或将其设置回1。然后将时间戳字段更新为当前日期


您能做得更简单吗?

用时间戳跟踪数据库中的每次访问(您可能已经这样做了)。然后创建一条sql语句并按天对结果进行分组,同时计算当天的访问次数。在过去30天内,不允许有0次访问日…

如果这是您唯一要记录的内容,那么这可能是一个好的解决方案。但是,我喜欢将逻辑和日志分开,这两种方法都可以增加我可以处理的原始信息量,并且允许在不破坏现有数据的情况下调整逻辑

在这种情况下,我会记录每次访问或每次操作(取决于需求/空间/等等),然后在某个地方编写一个存储过程或方法,检查数据并返回true(匹配徽章标准)或false(不匹配标准)


我会创建一个特定的模式来保存这样的信息的唯一情况是,如果所需的计算时间太长,或者是因为数据量太大,或者是因为数据太复杂。

我支持ropstah的方法。数据库中通常提供登录时间等用户统计信息。我们需要从现有数据中得出某些事实。因此,与每次访问都有一个计数器和递增的内容相比,我更喜欢在用户登录数据上运行的批处理作业,并发布当天的结果

但一旦一个用户“呜呜”了,你可能想停止计算该用户的“呜呜”度。
否则,用户每天都有可能被“求爱”,直到遇到一个不登录的日子。(但这是一个小问题)。

事实上,如果成员的访问在SQL数据库中,您可以通过一个SQL查询完成整个任务。这也可能比将所有数据传送到客户端程序进行检查要快:

/*
    Find all members who visited at least once every day
  for 30 or more days.  --RBarryYoung, 2009-05-31
*/
;WITH
  cteVisitDays as (
    Select
      MemberID
    , DATEDIFF(dd,'2008-06-01',VisitTime) as VisitDay
     From tblMembersLog
     Where Not Exists( Select * From tblMemberTags T
    Where T.MemberID = tblMembersLog.MemberID
     And T.TagName = 'WOOT!' )
     Group By MemberID
        , DATEDIFF(dd,'2008-06-01',VisitTime)
    )
, cteVisitRunGroups as (
    Select 
      MemberID
    , VisitDay - Row_Number() Over(
            Partition By MemberID
            Order By VisitDay
        ) as RunGrouping
     From cteVisitDays
     )
SELECT Distinct
  MemberID
 From cteVistRunGroups
 Group By MemberId, RunGrouping
 Having COUNT(*) >= 30

你确实需要一个cookie,因为人们可能不会每天登录——例如,因为他们会自动登录2周,或者因为他们在你的网站上不间断地做事情,不睡觉,不吃午饭,持续50个小时:)你可能真的想计算用户访问网站的时间

现在,理论上可以记录每次访问并执行数据库查询,正如上面所建议的,但您可能会认为(正如我所做的)它在有用性和隐私+简单性之间取得了错误的平衡

您指定的算法有一个明显的缺陷:因为您只存储了完整的天数,所以您错过了每12小时登录和注销一次的用户(您的算法将保留天数为1)

这是一个最干净的解决方案,每个用户有两个日期字段,采用一种不言自明的非面向对象Python:

# user.beginStreak----user.lastStreak is the last interval when 
# user accessed the site continuously without breaks for more than 25h 

def onRegister (user):
    ...
    user.beginStreak = user.endStreak = time() # current time in seconds 
    ...

def onAccess (user): 
    ...
    if user.endStreak + 25*60*60 < time():
        user.beginStreak = time()
    user.endStreak = time()
    user.wootBadge = ( user.endStreak-user.beginStreak > 30*24*60*60 )
    ...
#user.beginStreak---user.laststrick是
#用户无中断连续访问站点超过25小时
def onRegister(用户):
...
user.beginStreak=user.endStreak=time()#以秒为单位的当前时间
...
def onAccess(用户):
...
如果user.endStreak+25*60*6030*24*60*60)
...
(请原谅我的Pythonic技巧,我是一名学术人士,也是第一次使用网站)


不能使用一个变量执行此任务。我相信有人能写出一个清晰的论据来证明这一事实。

这是最佳解决方案。顺便问一下,为什么会有“呜呜”的徽章。原来的名字(“发烧友”)更好。为什么会有奇怪的字体?@Zifre,因为这是赞助服务器故障启动的公司的标志。这确实是一个非常有趣的问题,特别是作为一个练习,证明你不能用少于两个日期变量(或一个日期和间隔变量)来做这件事。我可能会选择我的第一个答案。。。我在找那个……你忘了那个需要饼干。为什么?只需将每次访问都存储在数据库中..?它不需要cookie。用户必须登录并与站点交互。将这一天标记为“活跃”是很容易的。向我解释为什么你需要一个cookie作为你登录的站点?哇,看起来很难看。用逗号开始一行会让我的眼睛流血。对不起,我在“操作员优先”代码格式化学校。“拖尾运算符”格式的代码在我看来很奇怪。不要让我开始使用双向的代码…当然,不同的格式样式对专业人士来说并不重要。只要它是一致的。不,不需要cookie,特别是如果您建议将“woot”计算中使用的任何数字存储在那里。规则#1:永远不要信任来自客户的数据。好吧,cookie之所以存在,是因为你所说的“访问站点”是指什么时候。如果你的意思是“用户登录”,你不需要cookie。如果您的意思是“用户两周前登录,但已返回”,那么您需要一个cookie。无论哪种方式,问题本身都是关于onAccess()中应该包含什么,而不是如何定义什么是访问。