我需要确定用户是否已访问过某个网页,以便跟踪唯一的网页浏览量。
我已经实现了一些HTTP头缓存,但现在我需要优化SQL查询。
在以下情况下,访问是独一无二的:
page_id
+ user_id
位于visit
表page_id
+ session_id
page_id
+ [ip
+ useragent
] - (这是另一个讨论的主题,是否只应该是ip或ip + useragent)所以我有一个跟踪用户访问的表格:
visit:
page_id
user_id
session_id
useragent
ip
created_at
updated_at
现在每次访问用户(没有点击缓存)我会更新一行(如果存在)。如果有任何受影响的行,我将在表中插入新访问。
这是一个或两个查询(假设缓存可以工作,主要是两个查询),但行数以某种方式受到限制。也许最好存储所有访问,然后在例如清理数据库中清理数据库。一个月?
问题是:
visit
表(键,索引,与user
和page_views
表的关系)。一些重要的字段可能为null(例如user_id),那么索引呢?我需要多列主键吗?我使用PostgreSQL和PDO(Doctrine ORM)。 我的所有会话都存储在同一个数据库中。
答案 0 :(得分:2)
我个人不会把它放在请求 - 响应路径中。我会将原始数据记录在表中(或将其推送到队列中)并让后台任务/线程/ cron作业处理。
队列(或消息传递表)应该只包含pageid,userip,sessionid,useragen,ip。
只要后台任务能够跟上,绝对时间就不那么重要了。由于单个线程现在将执行繁重的工作,因此在更新唯一的网页浏览表时不会产生冲突的锁。
答案 1 :(得分:0)
只是一些随意的想法:
我可以验证独特访问类型背后的想法是:
对于原始性能,您可能认为#2是冗余的,因为#3 可能覆盖#2 i大多数条件(或者#2重要,例如,如果用户然后注册然后#2可以被映射到#1)? (意味着会话ID可能仍会被记录,但不会在任何访问确定中使用)
IMHO IP将始终存在(即使是欺骗性的)并且将成为索引的良好候选者。用户代理可以隐藏,只有有限的范围(不是很容易选择)。
由于可空字段,我会在此实例中使用代理主键,因为没有字段本身是唯一的。
恕我直言,你的想法是存储所有访问,然后通过批量删除修剪重复是一个很好的权衡(而不是检查是否存在更新与插入新)