适用于web照片库的NoSQL数据模式



我想为照片库的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作为列。使用范围键反转也是一个好主意,可以轻松查询最后一行。

最新更新