1

私は紺碧のテーブルストレージ(注: Azure SQLではありません)を使用していますが、次の状況があります。

私のアプリケーションには、ユーザーを「招待」する多くの組織があり、招待には「役割」と「有効期限」が関連付けられています。組織がユーザーを招待したら、組織に招待されたユーザーのリストを表示させ、ユーザーに招待された組織のリストを表示させます。

私のアプリケーションとこの場合、数は少ないと思います(つまり、組織は少数のユーザーのみを招待し、ユーザーは通常1つの組織からのみ招待されます)。しかし、非常に多くの人がいる場合でも、人々がこの状況に対処するために使用する一般的なパターンはありますか?

4

1 に答える 1

4

ニーズに応じて、現在使用しているアプローチは3つあります。

トランザクション

順方向と逆方向の関係を同じパーティションに保存します...これは、すべてのエンティティが同じパーティションにあることを意味します(つまり、このメソッドは単一のパーティションによってレート制限されます)が、バッチトランザクションを使用して順方向を挿入できることを意味します同時に逆の関係。つまり、常に正しいことがわかります。

public class OrganisationInvite : TableEntity
{
    // Partition Id - string.Empty
    // Row Id - "Invite_" + OrangisationId + "_" + UserId

    public string Role { get; set; }
    public DateTime Expiry { get; set; }
}

public class OrganisationRequest : TableEntity
{
    // Partition Id - string.Empty
    // Row Id - "Request_" + UserId + "_" + OrganisationId

    public string Role { get; set; }
    public DateTime Expiry { get; set; }
}

クエリを実行するには、またはを使用してt.RowKey.StartsWith("Request_...")t.RowKey.StartsWith("Invite_...")ユーザー/組織の招待状のリストを取得するかどうかを決定します。

これは、データが非常に重要な場合に最もよく使用されると思います。

結果整合性

私は両方のテーブルにすべてのプロパティを与えますが、それらは異なるパーティションに存在します。これにより、優れたスケーラビリティが得られますが、トランザクションは失われます。メッセージングキューを使用して逆の関係を更新し、順の関係に一致させるため、最終的にデータが一致します。(しかし、しばらくの間はそうではないかもしれません)。

// Assume both in the same table, thus the prefix on partition
public class OrganisationInvite : TableEntity
{
    // Partition Id - "Invite_" + OrangisationId
    // Row Id -  UserId

    public string Role { get; set; }
    public DateTime Expiry { get; set; }
}

public class OrganisationRequest : TableEntity
{
    // Partition Id - "Request_" + UserId
    // Row Id - OrganisationId

    public string Role { get; set; }
    public DateTime Expiry { get; set; }
}

クエリを実行するには、またはを使用してt.PatitionKey == "Request_..."t.PatitionKey == "Invite_..."ユーザー/組織の招待状のリストを取得するかどうかを決定します。おそらく、これらの1つを「信頼できる情報源」と見なすため、ユーザーが招待を受け入れた場合は、「信頼できる情報源」を検索して、ユーザーにその役割などを与えることになります。

これは最もスケーラブルなソリューションであり、その上にキャッシュを使用している場合は特に意味があります。

真実の情報源

この場合、一方のエンティティにのみプロパティを指定し、もう一方のエンティティには逆の関係のキーのみを指定します。最も長い、または最もクエリが多いエンティティをリストに追加します...この場合、それは組織への招待であると言えます。結果整合性メソッドと同様に、逆関係をキューに入れて逆エンティティを追加します。この方法では、新しい関係を追加する場合を除いて、完全なデータの一貫性が得られ(逆の関係が作成されるまでに少し時間がかかるため)、拡張性が高くなります。ただし、逆のリストを読み取るにはコストが高くなります。

 // Assume both in the same table, thus the prefix on partition
public class OrganisationInvite : TableEntity
{
    // Partition Id - "Invite_" + OrangisationId
    // Row Id -  UserId

    public string Role { get; set; }
    public DateTime Expiry { get; set; }
}

public class OrganisationRequest : TableEntity
{
    // Partition Id - "Request_" + UserId
    // Row Id - OrganisationId
}

を使用して、フォワードリレーションシップを簡単にクエリできますt.PatitionKey == "Invite_..."。ただし、逆の関係は簡単ではありません。各アイテムのデータ転送データを取得するには、n個の並列呼び出しを使用してクエリを実行しt.PatitionKey == "Request_..."、作成する必要があります(この場合、逆の関係のRowKeyにある組織IDを使用します)。アイテムが存在しない場合は、最終リストに追加しません。これにより、たとえば組織がその役割を変更した場合、ユーザーは次のヒットでこの変更を確認できます。

この方法は、逆の関係がめったに使用されず、データが最新であることが重要である場合に役立つと思います(ユーザーのアクセス許可などを考えていますか?)

于 2013-02-09T23:39:13.680 に答える