我正在构建一个包含3列的简单友谊表:id,user1,user2
一旦用户成为另一个用户的朋友,他们的ID将被添加到表中,如下所示:
joinkey
上表是可以的,但在某些情况下,用户可能希望与他们已经是朋友的用户成为朋友,从而生成下表:
MCWarTeam
在此表中,索引1和3彼此冲突(2&3不是),因此我希望在插入时返回错误(重复条目)。有没有办法做到这一点?
答案 0 :(得分:4)
在插入此表时,在发出查询之前,应始终确保user1
具有两个用户ID中较小的一个。那么你描述的情况永远不会发生。
您可以在应用程序代码中实现此功能,也可以将其作为执行的存储过程在两个用户之间插入新关系。
答案 1 :(得分:3)
让我提出另一个观点。您可能希望将朋友表保持为互惠关系。因此,两个方向都将存储在表格中。正确的表格如下:
----+-------+-------+
| id | user1 | user2 |
+----+-------+-------+
| 1 | 15 | 9 |
+----+-------+-------+
| 2 | 9 | 15 |
+----+-------+-------+
| 3 | 9 | 32 |
+----+-------+-------+
| 4 | 32 | 9 |
+----+-------+-------+
为什么你想做一个荒谬的事情,把数据的大小加倍?对这些数据的典型查询是关于谁是朋友的朋友或列出给定用户的所有朋友。此类查询需要将此数据作为图形结构进行遍历,并且您需要两个链接。这种查询不仅因每个友谊单行而变得复杂得多,而且由于经常涉及子查询(派生表),查询将失去使用索引的能力。
使用此结构时,插入时需要小心插入关系的两个方向。然后,对两列的简单unique
约束确保不插入重复项。
答案 2 :(得分:2)
您可以创建一个触发器来自动修复此问题,类似于Dmytro的回答:
CREATE TRIGGER trgr_uid_check BEFORE INSERT ON Relationships
FOR EACH ROW
BEGIN
IF NEW.user1 > NEW.user2 THEN
SET @user1 = NEW.user1;
SET NEW.user1 = NEW.user2;
SET NEW.user2 = @user1;
END IF;
END
答案 3 :(得分:0)
你可以做一个简单的查询来检查是否已经有了友谊:
SELECT id
FROM your_table
WHERE (user1 = numToInsert1 AND user2 = numToInsert2)
OR (user1 = numToInsert2 AND user2 = numToInsert1)
如果此语句返回任何内容,则表示这两者之间已存在友谊。如果此声明没有返回任何内容,请插入新的友谊。