10

私のアプリケーションには、グループに所属できるユーザー向けの通知設定があります。グループ管理者はグループ全体の設定を定義できるため、いずれかのユーザーがアクションを実行すると管理者に通知されます。管理者は、グループ設定を上書きする個々のユーザーの設定を定義することもできます。

現在、列を持つデータベースがあります: group_id, action1, action2, action3, .... アクションは、そのアクションがグループ内のユーザーによって実行されたときに管理者に通知するかどうかを決定するブール値です。

Group モデルの代わりに User モデルが所有する別のテーブルを作成することもできますが、完全に別のテーブルにまったく同じデータを格納するのは非効率的group_idですuser_id

別のオプションは、user_id既に持っているテーブルに追加し、 に null 値を許可することですgroup_id。ユーザーの通知設定を決定するとき、アプリケーションは最初にユーザーに基づいて設定を選択し、group_idnull でない設定にフォールバックします。データベースには多くの null 値が存在するため、これは効率が悪いように感じますが、私の側での作業が少なくて済むことは間違いありません。

私が説明した 2 つよりも効率的なこの状況の設計はありますか?

4

2 に答える 2

22

一般に、このような状況を処理するには 2 つの戦略があります。

1. 排他的 FK を使用する

基本的に、可能な親テーブルのそれぞれは、子テーブルに独自の個別の外部キーを持ち、そのうちの1 つだけが非 NULL であることを強制する CHECK があります。FK は非 NULL フィールドにのみ適用されるため、FK の 1 つだけが適用されます。

例えば:

ここに画像の説明を入力

(ユーザーとグループの関係は省略)

CHECK (
    (group_id IS NOT NULL AND user_id IS NULL)
    OR (group_id IS NULL AND user_id IS NOT NULL)
)

2.継承を使用する

共通のスーパータイプからユーザーとグループを継承し、設定をスーパータイプに接続します。

ここに画像の説明を入力

継承 (別名、カテゴリ、サブクラス化、サブタイプ、汎化階層など) の詳細については、 ERwin Methods Guideの「サブタイプの関係」の章を参照してください。残念ながら、最近の DBMS は継承をネイティブにサポートしていません。継承を物理的に実装する方法については、この投稿を参照してください。

これは、おそらく 2 つのテーブル (グループとユーザー) だけでは正当化されない、負荷の高いソリューションですが、多くのテーブルに対して非常に「スケーラブル」になる可能性があります。

于 2012-11-09T23:21:28.650 に答える
0

代わりに Actions テーブルはどうですか?

次の列を含めることができます。

Table Actions:
ActionId - Identity columns
Action   - Store your action here; type would depend on your system
RefId    - The Id for either the user or the group
RefTable - either User or Group

次に、テーブルにアクセスするときに、自分の ID を既に知っており、それがグループかユーザーかを知っているので、適切なアクションを取得できます。

これは理にかなっていますか?

アップデート:

ユーザー/グループの両方に同じアクションを設定し、どちらかを優先する可能性がある場合 (Q で述べたように)、priority列を追加して、tinyInt- 数値が小さい = 優先度が高いように設定することもできます。次に、アクションを選択すると、この優先度で並べ替えることができます。次に、最初のアクション、または各アクションを順番に実行します。

于 2012-11-09T17:42:23.287 に答える