私の経験では、本当の問題は主に、ユーザー固有のアクセス制限が発生するかどうかに分類されます。
たとえば、コミュニティのスキーマを設計していて、ユーザーがプロファイルの表示を切り替えることができるようにするとします。
1つのオプションは、パブリック/プライベートプロファイルフラグに固執し、広範なプリエンプティブ権限チェックに固執することです。「users.view」(パブリックユーザーを表示)と「users.view_all」(モデレーターの場合はすべてのユーザーを表示) 。
もう1つは、より洗練された権限を含みます。(a)すべての人が表示できるようにし、(b)厳選された仲間が表示できるようにし、(c)完全に非公開にし、おそらく(d )厳選されたボゾを除くすべての人が見ることができます。この場合、個々の行の所有者/アクセス関連のデータを保存する必要があります。また、密集した有向グラフの推移閉包が実現しないように、これらのデータの一部を大幅に抽象化する必要があります。
どちらのアプローチでも、役割の編集/割り当ての複雑さの増加は、割り当ての結果として生じる容易さ/柔軟性によって相殺されることがわかりました。 個々のデータへのアクセス許可、および次のことが最も効果的に機能すること:
- ユーザーは複数の役割を持つことができます
- ロールと権限が同じテーブルにマージされ、2つを区別するためのフラグが付けられました(ロール/権限を編集するときに便利です)
- ロールは他のロールを割り当てることができ、ロールと権限は同じテーブル内からアクセス許可を割り当てることができます(ただし、アクセス許可はロールを割り当てることはできません)。
結果として得られる有向グラフは、2つのクエリで取得され、使用している言語を使用して妥当な時間内に一度だけ作成され、後で使用するためにMemcacheなどにキャッシュされます。
そこから、ユーザーのアクセス許可を取得するには、ユーザーがどの役割を持っているかを確認し、アクセス許可グラフを使用してそれらを処理して、最終的なアクセス許可を取得します。ユーザーが指定された役割/権限を持っているかどうかを確認して、権限を確認します。次に、クエリを実行し、その権限チェックに基づいてエラーを発行します。
個々のノードのチェックを拡張できます(つまり、check_perms($user, 'users.edit', $node)
「このノードを編集できます」とcheck_perms($user, 'users.edit')
の場合 「ノードを編集する可能性があります」)必要に応じて、エンドユーザーにとって非常に柔軟で使いやすいものが得られます。
冒頭の例で説明するように、行レベルのアクセス許可に向けて操作しすぎないように注意してください。パフォーマンスのボトルネックは、有効なノードのリストを取得する場合よりも、個々のノードのアクセス許可を確認する場合の方が少なくなります(つまり、ユーザーが表示または編集できるノードのみ)。クエリの最適化に(あまり)精通していない場合は、行自体のフラグとuser_idフィールド以外のものは使用しないことをお勧めします。