跟踪用户和照片他们';我看了


Keeping track of users and photos they've viewed

我有一个流量很高的网站,上面有很多照片,我正在努力跟踪每个用户查看了哪张照片。

我的第一直觉是一个有两列的SQL表:user_id&photo_id。但是,这不会扩展到我的流量水平,而且桌子很快就会变得难以管理
其他解决方案的任何建议,无论是SQL还是NoSQL(mongodb、couch、redis…)

如果这很重要的话,我的代码主要是PHP。

谢谢!

编辑每天有数以千万计的浏览量。

编辑我不需要知道用户查看特定照片的总次数,只需要知道该用户是否查看过该照片

您最好的选择是使用{_id:自动生成,pictureID,viewerID}创建一个集合

使用find(pictureID,viewerID).limit(1)和pictureID上的索引andviewerID将使检查达到超快速99级。设置索引非常重要。我使用find().limit(1)是因为它比findOne快,至少从当前的基准测试来看是这样。

为什么不让每个用户都有一个条目,其中包含一组已查看的图像?因为搜索数组比搜索集合中的整个文档慢。1000万张图片?没问题。这就是mongodb的闪光点。它是为像你这样的大数据库而设计的。只要你的文档小于16mb,并且有3个属性,那就是:)你就不用担心了。

当您删除图像时,只需db.viewed.remove({pictureID:pictureID}),它就会删除所有与图像相关的内容。

db.viewed.remove({viewerID:viewerID})用于删除用户!当用户删除图像或帐户时,不要执行此操作。在维护时执行此操作,或者说,每小时执行一次。使用pendingRemovingImages和pendingRemovangUsers创建一个集合,用于存储要删除的内容。在中选中$以按图像和/或按用户执行批量删除。

我觉得你的问题是最令人兴奋的,我强烈认为你应该朝我的方向去。

您可以试试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倍,最多可达TB。