我的网站流量非常高,网站上有很多照片,我正在尝试跟踪每位用户查看的照片。
我的第一直觉是一个包含两列的SQL表:user_id& photo_id。但是,这不会扩展到我的流量水平,并且表格将很快变得无法管理 任何关于anoher解决方案的建议,无论是SQL还是NoSQL(mongodb,沙发,redis,......)
如果重要,我的代码主要是PHP。
谢谢!
编辑每天有数百万的观看次数。
编辑我不需要知道用户查看特定照片的总时间,只需知道该用户是否已查看该照片
答案 0 :(得分:1)
最好的办法是创建一个{_id:自动生成,pictureID,viewerID}的集合
使用find(pictureID,viewerID).limit(1)和pictureID上的索引 AND viewerID将检查超级超快99级。设置索引非常重要。我使用find()。limit(1)因为它比findOne快,至少从当前的基准测试开始。
为什么每个用户只有一个条目有一个查看过的图像?因为搜索数组比搜索集合中的整个文档要慢。 1000万张图片?没问题。这是mongodb闪耀的地方。它旨在扩展您的大型数据库。只要你的文件少于16 mb,并且有3个属性,那就是:)你几乎不用担心。
删除图像时,只需db.viewed.remove({pictureID:pictureID}),它将删除所有与图像相关的内容。
删除用户时,db.viewed.remove({viewerID:viewerID})!当用户删除图像或帐户时,请勿执行此操作。在维护时间或每小时一次这样做。使用pendingRemovingImages和pendingRemovingUsers创建一个集合,您可以在其中存储要删除的内容。检查 $ in 以按图片和/或用户执行批量删除。
我觉得你的问题最令人兴奋,我强烈地感到你应该朝着我的方向前进。
答案 1 :(得分:1)
你可以尝试一下Redis。 Redis非常支持PHP,使用Redis,您可以将特定照片的查看历史记录存储在哈希映射中。
$map = 'views|' . $photo_id;
// this line is called whenever a user view a photo
$redis->hset($map, $uid, time());
// this line is called to test whether a user viewed a photo
$redis->hget($map, $uid);
Redis足够快。但是你应该知道的关于Redis的一件事是它将所有数据存储在内存中,所以如果数据最终超过物理内存,你必须自己对数据进行分片。
你也可以尝试SSDB(https://github.com/ideawu/ssdb),它有与Redis类似的API,也很好地支持PHP(http://www.ideawu.com/ssdb/docs/php/),但是将大多数数据存储在磁盘中,内存仅用于缓存。这意味着SSDB的容量是Redis的100倍 - 高达TBs。