を縮小しUNIQUE KEY
て、のみにすることができitem1_id
ます。これは、テーブルが関係を定義し、1:1
関係を定義しないことを意味します1:n
。さらに、auto_increment
主キーを削除できます。これらの「リンク」テーブルでは必要ありません。
CREATE TABLE IF NOT EXISTS links (
item1_id int(20) NOT NULL,
item2_id int(20) NOT NULL,
PRIMARY KEY (item1_id),
FOREIGN KEY (item1_id) --- I assume you have these 2
REFERENCES item (item_id), --- Foreign Keys, too
FOREIGN KEY (item2_id)
REFERENCES item (item_id)
) ENGINE=InnoDB;
これと@gbnの答えの違いは、これはNullを許可せず、リンクされていないアイテムを格納する必要がないことです。どちらのデザインもほぼ同じように機能しますが、Insert / Delete/Updateステートメントに若干の変更が加えられています。
ただし、どちらの設計でも、:、、、のようなカップルをリンクさせることが (1 -> 2)
でき(2 -> 3)
ます(3 -> 7)
。それが必要な仕様を満たしている場合は、両方の設計で問題ありません。
ただし、リンクのいずれかの側で、リンクされた1つのカップルにのみアイテムを表示する場合は、実装が難しくなります。
links
1つの方法は、テーブル内のすべての挿入が、両方(1, 2)
を挿入して(2, 1)
結合するか失敗する手順を介して行われるようにすることです(2行を処理する必要があるDelete / Updateステートメントの場合も同様です)。
他のより複雑な方法には、トリガー(または、MySQLでは使用できないインデックスビューなどのエキゾチックな構造)が含まれます。
正規化された設計が必要な場合は、このアプローチもあります(複雑ですがトリガーはありません)。
CREATE TABLE IF NOT EXISTS link_help (
item1_id int(20) NOT NULL,
item2_id int(20) NOT NULL,
PRIMARY KEY (item1_id),
FOREIGN KEY (item1_id)
REFERENCES item (item_id),
FOREIGN KEY (item2_id)
REFERENCES item (item_id),
UNIQUE KEY (item1_id, item2_id) --- this will be needed below
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS links (
item1_id int(20) NOT NULL,
item2_id int(20) NOT NULL,
PRIMARY KEY (item1_id),
FOREIGN KEY (item1_id, item2_id)
REFERENCES link_help (item1_id, item2_id),
FOREIGN KEY (item2_id, item1_id) --- notice the different
REFERENCES link_help (item1_id, item2_id) --- order here
) ENGINE=InnoDB;
(1 -> 2)
現在、テーブル(2 -> 3)
に(3 -> 7)
行を追加することはできません 。links