我有一个流量非常高的网站,上面有很多照片,并且正在尝试跟踪每个用户查看过的照片。
我的第一直觉是一个包含两列的 SQL 表:user_id 和 photo_id。但是,这不会扩展到我的流量级别,并且表格很快就会变得无法管理。
其他解决方案的任何建议,无论是 SQL 还是 NoSQL(mongodb、couch、redis、...)
如果重要的话,我的代码主要是 PHP。
谢谢!
编辑每天有数千万的浏览量。
编辑我不需要知道用户查看特定照片的总次数,只需要知道该用户是否查看过它
我有一个流量非常高的网站,上面有很多照片,并且正在尝试跟踪每个用户查看过的照片。
我的第一直觉是一个包含两列的 SQL 表:user_id 和 photo_id。但是,这不会扩展到我的流量级别,并且表格很快就会变得无法管理。
其他解决方案的任何建议,无论是 SQL 还是 NoSQL(mongodb、couch、redis、...)
如果重要的话,我的代码主要是 PHP。
谢谢!
编辑每天有数千万的浏览量。
编辑我不需要知道用户查看特定照片的总次数,只需要知道该用户是否查看过它
您最好的选择是使用 { _id:Generated automagically, 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以按图像和/或用户执行批量删除。
我发现你的问题最令人兴奋,我强烈认为你应该朝着我的方向前进。
你可以试试 Redis。Redis 很好地支持 PHP,使用 Redis,您可以将特定照片的查看历史存储在 hashmap 中。
$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 倍——高达 TB。