有没有一种很好的方法可以在单个表中实现行之间的多对多关系?
示例:用于存储单词同义词的表:
-- 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)
);
明显的解决方案可能导致非1NF表,包含重复数据:
INSERT INTO word_link(word1, word2) VALUES (1, 2);
INSERT INTO word_link(word1, word2) VALUES (2, 1);
虽然可以通过添加(word1< word2)检查来处理重复,但它使SELECT更复杂(与简单连接相比的联合)并且非常随意。这个特定情况可以从辅助表中受益(例如'含义',因此单词是M:N链接到常见含义而不是相互关联,给出更清晰的模式),但我对一些通用解决方案感兴趣。
那么实现这样的M:M关系是否有更好的(并且希望是常见的)方式?
答案 0 :(得分:1)
在这种情况下,我会在UPDATE和INSERT上添加一个CHECK CONSTRAINT来强制word1始终小于word2,反之亦然。
答案 1 :(得分: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
这样,你总是有一个干净的,没有重复的列表,很容易从中选择。我发现这是一种干净利落的方式,因为你可以做多对多的关系。