Mik*_*ley 5 mysql sql union composite-primary-key
我有一个带有主键_id的用户的MySQL表,我希望将友谊(在其他用户的朋友列表上的可见性)表示为具有成对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)
)
Run Code Online (Sandbox Code Playgroud)
这是我的理解是,这将允许(userIdA = 2, userIdB = 7)与(userIdA = 7, userIdB = 2)被插入的不同行.我想要每个友谊一行,也就是说每对userIds一行.
有谁知道我怎么能改善这个?即使满足上述约束,要获得用户foo的所有朋友的列表,我必须做一个联合,例如:SELECT userIdB AS friendUserId WHERE userIdA = foo UNION SELECT userIdA WHERE userIdB = foo.这是完成该查询的最佳方式,还是应该考虑更改我的架构?
您可以使用 aTRIGGER BEFORE INSERT来执行业务规则:
userIdA始终是具有较低 IDuserIdB的用户,始终是具有较高 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 ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
665 次 |
| 最近记录: |