Правильная схема данных NoSQL для веб-галереи фотографий
Я ищу для создания соответствующей структуры данных для NoSQL хранения фотогалереи. В моем веб-приложении фотография может быть частью 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? (В частности, Amazon DynamoDB.) Как выглядит хранилище? Как работает индексирование?
Ответы
Ответ 1
Используя mongodb lingo, ваши коллекции могут выглядеть так:
photos = [
{
_id: ObjectId(...),
title: "...",
date_uploaded: Date(...),
albums: [
ObjectId(...),
...
]
},
...
]
albums = [
{
_id: ObjectId(...),
title: "..."
}
]
Поиск пяти новых фотографий будет выполнен следующим образом:
> 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"}}});
Ответ 2
Redis может справиться с этим. Для таблицы RMDBS, о которой вы говорили выше:
SET фотографии: photo_id: название "некоторые фотографии заглавные слова"
SET фотографии: photo_id: date_uploaded "некоторое время загрузки (2011-02-09 HH: MM: SS, например)"
SET фотографии: photo_id: имя файла "некоторые имена файлов"
альбомы SET: album_id: название "названия некоторых альбомов"
SADD album_photo_map: photo_id album_id
Используйте список (список удалений 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) для photo_id в last_uploaded_photo_list для album_id в r.smembers(photo_id)]
Ответ 3
Используя DynamoDB, "схема" для таблицы фотографий может быть:
Album_Photo
- Идентификатор альбома (String, Основной ключ)
- Идентификатор фотографии (номер, диапазон)
- ... Другие поля
Теперь, когда я написал "Другие поля", вы могли сохранить все данные Фото и сохранить другой запрос для соответствующей таблицы данных, но это создало бы избыточные данные, если фотография существует во многих альбунах.
Вы можете сохранить все фотоданные в этой таблице для "основного" альбома, а в других альбунах использовать столбец для указания - это основной идентификатор альбома. Поскольку базам данных NoSQL не нужна строгая схема, в таблице не требуется столбец.
Если фотоид имеет какое-то поведение с автоматическим приращением, вы можете легко получить последние снимки X альбома. если нет, вы можете использовать клавишу "Дата как диапазон" и идентификатор фотографии в качестве столбца. Также неплохо использовать ваш ключ диапазона в обратном порядке, чтобы легко запросить последнюю строку.