Database design 如何跟踪用户在X天内每天访问站点的情况?
堆栈溢出上有一个新的标记。“徽章”颁发给每天访问网站的用户,为期30天。如何实现这样的功能?您如何以最简单的方式跟踪用户每天访问站点X天的情况 我想有两个字段——一个用于最后一次登录的时间戳,另一个用于计算用户连续访问站点的天数。逻辑是首先将计数器设置为1,并存储登录时间。在下一次登录时,检查自上次登录后是否没有超过一天,并增加计数器,或将其设置回1。然后将时间戳字段更新为当前日期Database design 如何跟踪用户在X天内每天访问站点的情况?,database-design,methodology,Database Design,Methodology,堆栈溢出上有一个新的标记。“徽章”颁发给每天访问网站的用户,为期30天。如何实现这样的功能?您如何以最简单的方式跟踪用户每天访问站点X天的情况 我想有两个字段——一个用于最后一次登录的时间戳,另一个用于计算用户连续访问站点的天数。逻辑是首先将计数器设置为1,并存储登录时间。在下一次登录时,检查自上次登录后是否没有超过一天,并增加计数器,或将其设置回1。然后将时间戳字段更新为当前日期 您能做得更简单吗?用时间戳跟踪数据库中的每次访问(您可能已经这样做了)。然后创建一条sql语句并按天对结果进行分组
您能做得更简单吗?用时间戳跟踪数据库中的每次访问(您可能已经这样做了)。然后创建一条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*60
(请原谅我的Pythonic技巧,我是一名学术人士,也是第一次使用网站)
不能使用一个变量执行此任务。我相信有人能写出一个清晰的论据来证明这一事实。这是最佳解决方案。顺便问一下,为什么会有“呜呜”的徽章。原来的名字(“发烧友”)更好。为什么会有奇怪的字体?@Zifre,因为这是赞助服务器故障启动的公司的标志。这确实是一个非常有趣的问题,特别是作为一个练习,证明你不能用少于两个日期变量(或一个日期和间隔变量)来做这件事。我可能会选择我的第一个答案。。。我在找那个……你忘了那个需要饼干。为什么?只需将每次访问都存储在数据库中..?它不需要cookie。用户必须登录并与站点交互。将这一天标记为“活跃”是很容易的。向我解释为什么你需要一个cookie作为你登录的站点?哇,看起来很难看。用逗号开始一行会让我的眼睛流血。对不起,我在“操作员优先”代码格式化学校。“拖尾运算符”格式的代码在我看来很奇怪。不要让我开始使用双向的代码…当然,不同的格式样式对专业人士来说并不重要。只要它是一致的。不,不需要cookie,特别是如果您建议将“woot”计算中使用的任何数字存储在那里。规则#1:永远不要信任来自客户的数据。好吧,cookie之所以存在,是因为你所说的“访问站点”是指什么时候。如果你的意思是“用户登录”,你不需要cookie。如果您的意思是“用户两周前登录,但已返回”,那么您需要一个cookie。无论哪种方式,问题本身都是关于onAccess()中应该包含什么,而不是如何定义什么是访问。