web-dev-qa-db-ja.com

マルチテナンシーと入れ子集合ツリー

私が取り組んでいるアプリケーションは 入れ子集合 を利用しています1 データベース内のツリー構造を表します。
アクセス制御の特定の領域を拡張して、他のクライアントの情報を表示できないようにする必要がある複数のクライアント(マルチテナンシー)をサポートする必要があります。
スライド69のこのプレゼンテーション に要約されているように、いくつかの理由から、より一般的な「ナイーブ」アプローチよりも入れ子集合アプローチを優先しました。

一見すると、ネストされたセット構造内には、マルチテナント環境内での使用を妨げるような問題はないように見えます。ただし、ネストされたセットに関する懸念の1つは、必要な更新の数です。リーフノードは追加または削除されます。たとえば、挿入されたリーフノードの右側にあるすべてのエントリでは、左右の値を更新する必要があります。

問題のテーブルの場合、複数のテナントがある場合でも、常に比較的小さいままです(〜5〜10k行、トップ)。

また、ネストされたセットツリーを介して表現されたACLによって提供されるもの以外に、追加のアクセス制限が必要なクライアントもいます。

クライアントのアクセス制限を満たし、データベースの更新に関する潜在的な懸念に対処するために、ネストされたセットテーブルにClientIdフィールドを追加することを検討しています。あるクライアントのツリーを更新しても、他のクライアントのツリーに影響を与える必要はないという考えです。同様に、Clientフィールドが一致しないために、クライアントAがクライアントBのデータに誤ってアクセスしようとした場合、ハードブロックが設定されます。

 | RowId | ClientId |左|右| Foo ... |バー... | 
 | ---- ---------- | ------ | ------- | ----- --- | -------- | 
 | 3 | 10 | 1 | 42 | ... | ... | 
 | 5 | 20 | 1 | 69 | ... | | 

私が抱えている問題の1つは、他のクライアント( "Client 10"、 "Client 20"など)のアクションを実行するユーザーのセット( "ClientId 0"と呼びます)があることです。また、「クライアント0」が実行するアクションは、アクションを実行したクライアントが表示/使用できる必要があります。したがって、「クライアント0」は、異なるClientIdを受け取るものを作成する必要があります。2


このアプローチは健全であるように見えますか、それとも上記で説明したようにそれが維持されるかどうかを理解するために何を調べる必要がありますか?
あるいは、マルチテナントの階層情報を表すための優れたデータ構造はありますか?

1ネストされたセットツリー構造の実装の詳細については、スライド53から始まる---(このスライドデッキ も参照してください。
2これを解決するための私の作業アプローチは、クライアント0が作業しているノードからClientIdをプルし、ノードのClientIdを新しく作成されたノードに割り当てることです。

1
user53019

「テナント」列(この場合はClientId)を追加し、それを使用してテナントでフィルタリングすることは、テナントごとに個別のデータベースを持つことと論理的に同じです。唯一の違いは、どこでもそれを使用することを忘れないでください。これは、ネストされたセットだけでなく、データベース内のすべてに当てはまります。ストアドプロシージャの記述に注意を払っていれば、安全です。

選択した階層表現で見つけた長所または短所は、マルチテナントデータベースにした後も引き続き存在します。唯一の違いは、各クエリで行う作業が少し増えることです。

2
Frank Hileman