20

フォトギャラリーのNoSQLストレージに適切なデータ構造を構築したいと考えています。私のWebアプリケーションでは、写真を1つ以上のアルバムの一部にすることができます。私はMySQLの経験がありますが、Key-Valueストレージの経験はほとんどありません。

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 Key-Valueペアデータベースを使用して同様のクエリを実行するにはどうすればよいですか?(具体的には、AmazonのDynamoDBです。)ストレージはどのようになりますか?インデックス作成はどのように機能しますか?

4

3 に答える 3

12

mongodb lingoを使用すると、コレクションは次のようになります。

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"いくつかの写真のタイトルの単語"
SETphotos:photo_id:date_uploaded "いくつかのアップロードされた時間(たとえば、2011-02-09 HH:MM:SS)"
SET photos:photo_id:filename"いくつかのファイル名の単語"

SET albums:album_id:title"いくつかのアルバムタイトルの単語"

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)for photo_id in last_uploaded_photo_list for album_id in r.smembers(photo_id)]

于 2012-02-09T04:44:45.920 に答える
1

DynamoDBを使用すると、写真テーブルの「スキーマ」は次のようになります。

Album_Photo

  • アルバムID(文字列、主キー)
  • 写真付き身分証明書(番号、レンジキー)
  • ...その他のフィールド

さて、私が他のフィールドを書いたところで、すべての写真データを保存し、適切なデータテーブルに対する別のリクエストを保存できますが、写真が多くのアルバムに存在する場合、これは冗長データを作成します。

このテーブルの「メイン」アルバムのすべての写真データを保存できます。他のアルバムでは、列を使用してメインアルバムIDを指定します。NoSQLデータベースは厳密なスキーマを必要としないため、テーブルに列は必要ありません。

photoIDに何らかの自動インクリメント動作がある場合は、アルバムの最後のX枚の写真を簡単に取得できます。そうでない場合は、日付を範囲キーとして使用し、写真IDを列として使用できます。最後の行を簡単に照会するには、範囲キーを逆にして使用することもお勧めします。

于 2012-02-03T17:49:05.880 に答える