我想为照片库的NoSQL存储构建一个合适的数据结构。在我的web应用程序中,一张照片可以是一个或多个相册的一部分。我有MySQL的经验,但在键值存储方面几乎没有经验。
使用MySQL,我会设置如下(3)个表:
photos (photo_id, title, date_uploaded, filename)
albums (album_id, title, photo_id)
album_photo_map (photo_id, album_id)
然后,要检索5张最新照片的列表(包括相册数据),可以执行以下查询:
SELECT *
FROM albums, photos, album_photo_map
WHERE albums.album_id = album_photo_map.album_id AND
photos.photo_id = album_photo_map.photo_id
ORDER BY photos.date_uploaded DESC LIMIT 5;
如何使用NoSQL键值对数据库完成类似的查询?(特别是亚马逊的DynamoDB。)存储会是什么样子?索引是如何工作的?
使用mongodb语言,您的集合可能如下所示:
photos = [
{
_id: ObjectId(...),
title: "...",
date_uploaded: Date(...),
albums: [
ObjectId(...),
...
]
},
...
]
albums = [
{
_id: ObjectId(...),
title: "..."
}
]
找到5张最新的照片会这样做:
> var latest = db.photos.find({}).sort({date_uploaded:1}).limit(5);
mongo中没有服务器端连接,所以你必须像这样获取所有最新专辑:
> var latest_albums = latest.find({}, {albums: 1});
当然,然后你必须把它煮成一套。
实际上,如果你只是把相册嵌入照片文档中会更容易,因为它们很小:
photos = [
{
_id: ObjectId(...),
title: "...",
date_uploaded: Date(...),
albums: [
{name: "family-vacation-2011", title: "My family vacation in 2010"},
...
]
},
...
]
那么查询是一样的,但您不必加入。在相册中查找所有照片看起来像:
> db.photos.find({albums:{$elemMatch:{name: "family-vacation-2011"}}});
Redis可以处理这个问题。对于您上面提到的RMDBS表格:
设置照片:photo_id:title"一些照片标题词"
SET photos:photo_id:date_uplooaded"上传了一些时间(例如2011-02-09 HH:MM:SS)"
设置照片:photo_id:filename"一些文件名单词"
SET相册:album_id:title"一些相册标题词"
SADD白蛋白_photo_map:photo_id白蛋白_id
使用列表(Redis支持列表)存储上次上传的照片,并在上传新照片时更新列表:
ret=r.lpush("upload:last_upload_times",photo_id)//更新列表
ret=r.ltrim("upload:last_upload_times",0,N-1)//控制列表长度
然后,如果我们想获得最后上传的N张带有相册数据的照片:
last_upload_photo_list=r.lrange("上传:last_upload _times",0,N-1)last_uploaded_photo_with_album_list=[(photo_id,album_id)for photo_id in last_uploadd_photo_list for album_idin r.smembers(photo_id)]
使用DynamoDB;模式";照片表可以是:
相册_照片
- 专辑ID(字符串,主键)
- 照片ID(编号、量程键)
- 。。。其他字段
现在,在我写"其他字段"的地方,你可以保存所有照片数据,并保存另一个对正确数据表的请求,但如果照片存在于许多Albun中,这将创建冗余数据。
您可以将该表中的所有照片数据保存为";主";album,而在其他albun中,使用一列来指定是主album ID。由于NoSQL数据库不需要严格的模式,因此表中不需要列。
如果photoID有某种自动递增的行为,你可以很容易地获得相册的最后X张照片。如果没有,您可以使用日期作为范围键,并使用照片ID作为列。使用范围键反转也是一个好主意,可以轻松查询最后一行。