20

我正在寻找为照片库的 NoSQL 存储构建适当的数据结构。在我的 Web 应用程序中,一张照片可以是 1 个或多个相册的一部分。我有使用 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。)存储会是什么样子?索引将如何工作?

4

3 回答 3

12

使用 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"}}});
于 2012-02-05T20:07:44.883 回答
3

Redis 可以处理这个问题。对于您上面提到的 RMDBS 表:

SET photos:photo_id:title "一些照片标题词"
SET photos:photo_id:date_uploaded "一些上传时间(例如2011-02-09 HH:MM:SS)"
SET photos:photo_id:filename "一些文件名词"

SET Albums:album_id:title "一些专辑标题词"

SADD专辑照片地图:照片ID专辑ID

使用 List(Redis 支持列表) 存储上次上传的照片,并在上传新照片时更新列表:

ret = r.lpush("upload:last_upload_times", photo_id) // 更新列表
ret = r.ltrim("upload:last_upload_times", 0, N-1) // 控制列表长度

那么,如果我们想获取最后上传的 N 张照片和相册数据:

last_uploaded_photo_list = r.lrange("upload:last_upload_times", 0, N-1) last_uploaded_photo_with_album_list = [(photo_id, album_id) for photo_id in last_uploaded_photo_list for album_id in r.smembers(photo_id)]

于 2012-02-09T04:44:45.920 回答
1

使用 DynamoDB,照片表的“模式”可以是:

相册_照片

  • 专辑 ID(字符串,主键)
  • 照片 ID(数字,范围键)
  • ... 其他领域

现在,在我编写“其他字段”的地方,您可以保存所有照片数据并为正确的数据表保存另一个请求,但如果照片存在于许多 albuns 中,这将创建冗余数据。

您可以将“主”相册的所有照片数据保存在此表中,并在其他 albuns 中使用列指定主相册 ID。由于 NoSQL 数据库不需要严格的模式,因此表中不需要列。

如果 photoID 具有某种自动增量行为,您可以轻松获取相册的最后 X 张照片。如果没有,您可以将日期用作范围键,并将照片 ID 用作列。使用您的范围键反转也是一个好主意,以便轻松查询最后一行。

于 2012-02-03T17:49:05.880 回答