1

私はWindowsAzureテーブルストレージを使用して数百万のエンティティを格納していますが、次の2つのことを簡単に実現できる最適なソリューションを見つけようとしています。

1)エンティティを検索すると、そのエンティティと、そのエンティティの両側に少なくとも(pageSize)個のエンティティが取得されます

2)そのエンティティのいずれかの側に(pageSize)数を超えるエンティティがある場合、次のページまたは前のページのリンクが表示されます。これは、開始または終了のいずれかに到達するまで続きます。

3)順序は時系列の逆順です

各コンテナはシステム内で一意であるため、PartitionKeyはユーザーが提供するタイトルになることにしました。RowKeyは、SteveMarxの語彙アルゴリズムです。

http://blog.smarx.com/posts/using-numbers-as-keys-in-windows-azure

これは、c#ではなくjavascriptに変換すると、次のようになります。

pad(new Date(100000000 * 86400000).getTime()-new Date()。getTime()、19)+ "_" + uuid()

uuid()は、guidを返すjavascript関数であり、padは最大19文字の長さのゼロを追加します。したがって、システム内のレコードは次のようになります。

PK                                   RK
TEST    0008638662595845431_ecf134e4-b10d-47e8-91f2-4de9c4d64388
TEST    0008638662595845432_ae7bb505-8594-43bc-80b7-6bd34bb9541b
TEST    0008638662595845433_d527d215-03a5-4e46-8a54-10027b8e23f8
TEST    0008638662595845434_a2ebc3f4-67fe-43e2-becd-eaa41a4132e2

このパターンにより、挿入されたすべての新しいエンティティを、上記のポイント番号3を満たすリストの一番上に配置できます。

システムに新しいレコードを追加する良い方法で、RowKeyの前半、つまり0008638662595845431_部分を調べ、すでに見つかったアイテムの方向に応じて比較よりも大きいまたは小さいメカニズムを作成すると思いました。言い換えると、0008638662595845431の直前の行を取得するには、次のようなクエリを実行します。

var tableService = azure.createTableService();
var minPossibleDateTimeNumber = pad(new Date(-100000000*86400000).getTime() - new Date().getTime(), 19);

tableService.getTable('testTable', function (error) {
    if (error === null) {
        var query = azure.TableQuery
            .select()
            .from('testTable')
            .where('PartitionKey eq ?', 'TEST')
            .and('RowKey gt ?', minPossibleDateTimeNumber + '_')
            .and('RowKey lt ?', '0008638662595845431_')
            .and('Deleted eq ?', 'false');

返された結果が1000を超え、azureが継続トークンを提供する場合、最後の項目RowKey、つまり数値部分0008638662595845431を覚えていると思いました。したがって、次のクエリでは、記憶された値が開始値などになります。

私はWindowsAzureNode.Js SDKを使用しており、言語はjavascriptです。

誰かがこのアプローチの落とし穴や問題を見ることができますか?

4

1 に答える 1

1

特に前のページの行を取得するために、これがどのように効果的かつ効率的に機能するかわかりません。

効率的にするには、「キー」のプレフィックスは、タイムスタンプに基づくのではなく、値を連続的にインクリメントまたはデクリメントする必要があります。タイムスタンプで生成された値には、重複と穴が含まれるため、ページサイズから行数へのマッピングは、せいぜい非効率的であり、最悪の場合、決定が困難になります。

また、この潜在的なアルゴリズムは単一のパーティションキーに依存しているため、テーブルのスケーラビリティが損なわれます。

ここでの課題は、シリアルにインクリメントされるキーを生成する方法を用意することです。1つの解決策は、SQLデータベースを使用し、単一の行に対してアトミック更新を実行して、値の増分または減分が順番に生成されるようにすることです。UPDATE…SETX= X+1のようなものでXを返します。おそらくストアドプロシージャを使用します。

したがって、キーは、ゼロで左に埋め込まれたシリアル生成された番号である可能性があります。番号の最初のN桁がパーティションキーで、残りのM桁が行キーになるように分割します。

For example 
PKey    RKey
00001   10321
00001   10322
….
00954   98912

これで、行が順番に並んでいるため、ページサイズの正確なキー範囲を使用してクエリを作成できます。

警告。シリアルキーの生成とテーブルストレージへの書き込みの間に障害が発生するリスクはわずかです。その場合、テーブルに穴が開いている可能性があります。ただし、ページングアルゴリズムは、必要よりもわずかに大きいページサイズを指定するか、調整された範囲で再試行することにより、このようなインスタンスを非常に簡単に検出して回避できる必要があります。

于 2012-05-19T07:26:45.917 に答える