mysql - 无序的 SQL 组合主键(任意顺序的整数对必须是唯一的)

标签 mysql sql union composite-primary-key

我有一个主键为 _id 的用户 MySQL 表,我想将友谊(在其他用户的 friend 列表中的可见性)表示为具有 userId 外键对的表。我在想类似的东西:

CREATE TABLE UserFriendships (
  userIdA INT NOT NULL,
  userIdB INT NOT NULL,
  PRIMARY KEY (userIdA, userIdB),
  FOREIGN KEY (userIdA) REFERENCES Users(_id)
  FOREIGN KEY (userIdB) REFERENCES Users(_id)
)

据我了解,这将允许 (userIdA = 2, userIdB = 7)(userIdA = 7, userIdB = 2) 作为不同的行插入.我希望每个友谊一行,也就是说每对 userIds 一行。

有谁知道我该如何改进它?即使满足上述约束,要获得用户 foo 的所有 friend 的列表,我必须做一个联合,类似于: >。这是完成该查询的最佳方式,还是我应该考虑更改我的架构?

最佳答案

您可以使用 TRIGGER BEFORE INSERT 来执行业务规则:

  • userIdA 始终是 ID 较低的用户,userIdB 始终是 ID 较高的用户

这样,组合 (A,B) 和 (B,A) 会产生具有相同主键的相同列顺序。

DELIMITER |
CREATE TRIGGER enforce_friendship_id_order BEFORE INSERT ON UserFriendships
  FOR EACH ROW BEGIN
    SET @lowerId := IF(NEW.userIdA < NEW.userIdB, NEW.userIdA, NEW.userIdB);
    SET @higherId := IF(NEW.userIdA > NEW.userIdB, NEW.userIdA, NEW.userIdB);
    SET NEW.userIdA = @lowerId;
    SET NEW.userIdB = @higherId;
  END;
|
DELIMITER ;

关于mysql - 无序的 SQL 组合主键(任意顺序的整数对必须是唯一的),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15732764/

相关文章:

php - 如何使用 php 从 Linux 服务器连接到 Windows 服务器中的数据库?

php - 使用 mysqli 插入带有 if 条件的值

php - PHP 中的无效代码或消息

MySQL 查询 - 选择邮政编码匹配

mysql - MySQL bigint转UUID的存储过程

c# - 如何为 SQL CLR 存储过程提供 sql_variant 参数?

sql - 如何在 Postgres 中将 3 个表组合在一起?

c++ - union 成员的 offsetof 总是零吗?

php - MySQL 'select WHERE like x OR y' 一行有多个结果

mysql - 是否可以将此业务逻辑放在 SQL 查询中?