您可以将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;
this 和@gbn 的答案的区别在于,这不允许 Nulls,并且不需要任何东西来存储未链接的项目。两种设计的工作方式几乎相同,只是对 Insert/Delete/Update 语句稍作修改。
不过,在这两种设计中,我们都可以有如下链接的情侣:(1 -> 2)、(2 -> 3)、(3 -> 7)。如果这符合所需的规范,那么两种设计都可以。
但是,如果我们只希望项目只出现在一对链接的对中,那么在链接的任一侧,实现起来就更难了。
一种方法是确保links 表中的所有插入都是通过插入(1, 2) 和(2, 1) 对或失败的过程完成的(对于必须处理的删除/更新语句也是如此有 2 行)。
其他更复杂的方式涉及触发器(或奇异结构,如索引视图,在 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;
现在,您无法在links 表中添加(1 -> 2)、(2 -> 3)、(3 -> 7) 行。