2009-07-15 23 views
3

単一テーブルの行間に多対多の関係を実装する良い方法はありますか?多対多自己参照テーブル

例:複製は(WORD1 <を添加することによって対処することができるが

INSERT INTO word_link(word1, word2) VALUES (1, 2); 
INSERT INTO word_link(word1, word2) VALUES (2, 1); 

:ストア・ワードの同義語のテーブル:重複データを含む、おそらくない、1nFのテーブルで

-- list of words 
CREATE TABLE word (
    id integer  PRIMARY KEY, 
    word varchar(32) NOT NULL UNIQUE 
); 
INSERT INTO words (id, word) VALUES (1, 'revolve'); 
INSERT INTO words (id, word) VALUES (2, 'rotate'); 

-- M:M link between words 
CREATE TABLE word_link (
    word1 integer  REFERENCES word(id) NOT NULL, 
    word2 integer  REFERENCES word(id) NOT NULL, 
    PRIMARY KEY (word1, word2) 
); 

明白な解決策の結果、 word2)をチェックすると、SELECTをはるかに複雑にします(簡単な結合との比較)。かなり自由です。このような特殊なケースは補助テーブル(「意味」など)から利益を得ることができます。つまり、共通の意味にリンクされたM:Nであり、お互いにではなく、よりクリーンなスキーマです。

このようなM:M関係を実装するには、より良い(うまくいけば共通の)方法がありますか?

答えて

1

この場合、UPDATEとINSERTにCHECK CONSTRAINTを追加して、word1は常にword2よりも小さく、その逆も実行するようにします。

0

私は以下の通りであったビューを作成したい:

select distinct 
    case when word1 < word2 then word1 else word2 end as word1, 
    case when word1 < word2 then word2 else word1 end as word2 
from 
    word_link 

その方法は、あなたが常にから選択するのは簡単ですきれいな、重複リストを持っていません。私はそれが多対多の関係をしなければならないほどのきれいな方法であることを発見しました。

+0

ummm ...あなたのcase文には、両方の場合で同じ基準があります。私はあなたが単語2を意味すると仮定します。第2の単語のための単語1 –

+1

@Nathan:同じ条件、異なる結果。最初の列は常に小さい単語を使用し、2番目の条件は常に最大の単語を使用します。 – Eric

+0

ah私は今理解している –