AmazonのDynamoDBを見ているのは、データベースサーバーのメンテナンスとスケーリングの面倒をすべて取り除くように見えるからです。私は現在MySQLを使用していますが、データベースの保守とスケーリングは完全な頭痛の種です。
私はドキュメントを調べましたが、データを簡単に取得できるようにデータをどのように構成するかについて頭を悩ませるのに苦労しています。
私は、NoSQLおよび非リレーショナルデータベースを初めて使用します。
Dynamoのドキュメントからは、プライマリハッシュキーと、限られた数の比較演算子を使用したプライマリレンジキーでのみテーブルをクエリできるように思えます。
または、全表スキャンを実行し、それにフィルターを適用できます。キャッチは一度に1Mbしかスキャンしないため、X回の結果を見つけるにはスキャンを繰り返す必要があります。
これらの制限により、予測可能なパフォーマンスを提供できることがわかりますが、データを取り出すのは本当に難しいようです。そして、テーブル全体のスキャンを実行するseemsそれは本当に非効率的で、テーブルが大きくなるにつれて時間の経過とともに効率が悪くなるだけです。
たとえば、Flickrのクローンを持っていると言います。私の画像テーブルは次のようになります。
クエリを使用すると、過去7日間のすべての画像を一覧表示し、X個の結果に簡単に制限できます。
しかし、特定のユーザーのすべての画像を一覧表示する場合は、全表スキャンを実行し、ユーザー名でフィルタリングする必要があります。タグについても同じことが言えます。
また、一度に1Mbしかスキャンできないため、X個の画像を見つけるために複数回スキャンする必要がある場合があります。また、X個の画像で簡単に停止する方法も見当たりません。 30枚の画像を取得しようとしている場合、最初のスキャンで5枚、2回目のスキャンで40枚が見つかります。
これは正しいですか?基本的にトレードオフですか?事実上メンテナンスフリーで、非常に高速で予測可能なデータベースのパフォーマンスが得られます。しかし、トレードオフは、結果を処理するためにより多くのロジックを構築する必要があるということですか?
または、私はここで完全にオフになっていますか?
はい、パフォーマンスとクエリの柔軟性のトレードオフについては正しいです。
しかし、痛みを軽減するためのいくつかのコツがあります。おそらく、セカンダリインデックス/非正規化が最も重要です。
たとえば、ユーザーIDをキーとする別のテーブルがあり、すべての画像がリストされます。画像を追加すると、このテーブルを更新するとともに、画像IDをキーとするテーブルに行を追加します。
必要なクエリを決定してから、それらに基づいてデータモデルを設計する必要があります。
別のテーブルを使用して、独自のセカンダリインデックスを作成する必要があると思います。
このテーブル「スキーマ」は次のとおりです。
User ID (String, Primary Key)
Date Added (Number, Range Key)
Image ID (Number)
-
そうすれば、ユーザーIDでクエリを実行し、日付でフィルタリングすることもできます
composite hash-range keyをプライマリインデックスとして使用できます。
DynamoDBページから:
主キーは、単一属性のハッシュキーまたは複合ハッシュ範囲キーのいずれかです。単一の属性ハッシュプライマリキーは、たとえば「UserID」です。これにより、特定のユーザーIDに関連付けられたアイテムのデータをすばやく読み書きできます。
複合ハッシュ範囲キーは、ハッシュキー要素と範囲キー要素としてインデックス付けされます。このマルチパートキーは、最初の要素値と2番目の要素値の間の階層を維持します。たとえば、複合ハッシュ範囲キーは、「UserID」(ハッシュ)と「Timestamp」(範囲)の組み合わせにすることができます。ハッシュキー要素定数を保持して、範囲キー要素を検索してアイテムを取得できます。 これにより、クエリAPIを使用して、たとえば、タイムスタンプの範囲で単一のUserIDのすべてのアイテムを取得できます。