2011-01-05 6 views
0

問題に関連するデータベースパターンがあるかどうかは特に分かりませんでしたので、私は自分の質問のタイトルにどのような言葉を入れるのか苦労しました。できるだけ問題を簡素化して、問題の中心に直接向かおうとします。このような単純な制約のためにトリガーを書く必要がありますか?

テーブルがあるとします。 最初のものは、ウィジェットタイプのリストです:

create table widget_types (
    widget_type_id number(7,0) primary key, 
    description varchar2(50) 
); 

次はアイコンが含まれています

create table icons (
    icon_id number(7,0) primary key, 
    picture blob 
); 

、ユーザーが好みのウィジェットを選択するために取得するにもかかわらず、そのウィジェットの定義済みのサブセットがありますそれぞれのウィジェットタイプから選択できます。

create table icon_associations (
    widget_type_id number(7,0) references widget_types, 
    icon_id number(7,0) references icons, 
    primary key (widget_type_id, icon_id) 
); 

create table icon_prefs (
    user_id number(7,0) references users, 
    widget_type_id number(7,0), 
    icon_id number(7,0), 
    primary key (user_id, widget_type_id), 
    foreign key (widget_type_id, icon_id) references icon_associations 
); 

かなり簡単です。

ここで、自分の設定を設定していないユーザーにアイコンを表示している場合、現在のウィジェットに関連付けられた適切なイメージの1つを選択します。私は、このような場合に表示する優先アイコンを指定するために好きで、ここで私は私の問題に遭遇するところだと思います:

alter table icon_associations 
    add (is_preferred char(1) check(is_preferred in ('y','n'))) 
; 

私はそれぞれのためにそれを強制することができますどのように表示されていないWIDGET_TYPE 1がある、とだけ1、is_preferredが 'y'に設定されている行。

私はMySQLでこの問題をすばやく解決するためにチェック制約にサブクエリを書くことができます。これはOracleでは不可能です。

私の間違いは、この列はicon_associationsテーブル内に存在しないということですか?どこに行けばいいの?これは、Oracleでは、制約はトリガーでしか処理できないケースですか?

可能であれば、私が制約ルートに行きたいと思っているからです。

おかげであなたの助けのために、私はあなたの問題を解決信じる ポール

答えて

0

一つの簡単な方法は、別のテーブルを持つことであるので、多くは

icon_default_associations (widget_type_id, icon_id) 

と呼ばれ、単に(widget_type_id, icon_id)がUNIQUE制約に従う(またはメイク作りますそれはプライマリキーです)。

あなたがしようとしているようにするなら、あなたはicon_associationsの目的を過負荷にしていると思います。

+0

ただし、これにより、複数の優先アイコン(アイコンが指定されている場合)の作成が禁止されます。私はまだ好ましいものとして印を付けずにアイコンを指定することができます。 –

+0

icon_associationsの目的が行く限り、私はその感情も持っていました。しかしどちらも私はそれを過度に伸ばしたと確信しています。 –

+0

すべてのアイコンの優先度を1にしたい場合は、 "default_widget_association"というアイコンテーブルに別の列を追加して、NULLにしない方が良いと思います。次に、私の提案するicon_default_associationsテーブルを削除することができます。また、icon_associationsテーブルの名前を変更することもできます。 – kvista

0

デフォルトのアイコンが変更されない場合は、最初にデフォルトのアイコンがicon_associationsテーブルに入ることを確認できますか?

このようにして、1つのデフォルトアイコンだけが常に保証されます。アイコンがある限り離れることはなく、is_preferred列、またはその制約とトリガーでfutzする必要はありません。

また、デフォルトのアイコンを取得するのは簡単だろう:

SELECT * from icon_associations WHERE ID=MIN(ID) 

欠点は、デフォルトのアイコンを変更する作業を少し必要になるということですが、それが起こることはありませんならば、これはあなたのis_preferred列の問題を解決。

+0

それは巧妙な解決策です。私はこのような使い勝手が良いほど幸運ではない。 (私の問題はアイコンの問題より複雑ですが、似ています)。それは、バイナリの好みの値ではなく数値の列を持つことができると私に思い出させます。それは私が更新の制約を延期する必要はないということです。しかし、それは一番ランクの高いアイコンを選択するのが難しくなります。 –