首先,我的基本结构如下。
friends
表,添加了一些示例关系:
-------------------------------
|user1 | user2 | util1 | util2|
-------------------------------
| 123 | 456 | 123 | 456 |
| 789 | 012 | 012 | 789 |
| 345 | 678 | 345 | 678 |
(util
列是与我拥有的触发器关联的辅助列 - 如果存在(user1,user2) = (123,456)
,那么我不希望能够创建(456,123)
。触发器将(util1,util2)
作为(least,greatest)
插入;然后就会有一个唯一的索引。这很好,我想解释一下。)
friendReq
待处理的朋友请求表:
----------------
|initBy| reqTo |
----------------
| 901 | 234 |
| 567 | 890 |
| 234 | 567 |
什么有效:如果id 901
的用户请求234
,则该请求会添加到好友请求表中(如果它尚不存在);我在(initBy,reqTo)
上有一个唯一索引,因此,如果901
向234
重新发送请求,则不会插入和添加额外行。凉。
我需要的是:如果234
随后向901
发送了请求,我不希望插入(initBy,reqTo) = (234, 901)
(请注意,我已经设置了901
时234
1}}请求234
,234
收到通知;这很好。我只是假设901
忽略了请求并决定尝试手动添加(901,234)
我简单的文字字段+添加朋友按钮)。相反,我希望它自动接受好友请求 - 也就是说,从friendReq
删除friends
并将该关系添加到INSERT INTO friendReq ( initBy, reqTo)
VALUES ($userid, (SELECT id FROM users WHERE username = '$addFriend') );
。这里没有个人资料页面 - 没有Facebook风格的“回复朋友请求”选项。这是一个简单的基于跟随者的应用程序,只需输入用户名并单击添加即可请求友谊。
我的功能SQL只是添加好友请求而不检查我刚刚描述的内容:
$addFriend
(234
来自给定用户输入的用户名以发送好友请求;请不要注意防止SQL注入,这只是我的简化示例。)
伪代码,假设901
向IF (234, 901) DOES NOT EXIST
INSERT INTO friendReq ( initBy, reqTo)
VALUES ( 234, 901 )
IF (901, 234) EXISTS
INSERT INTO friends (901, 234),
DELETE FROM friendReq (901, 234);
发送请求:
$query = "SELECT * FROM friendReq
WHERE initBy = (SELECT id FROM users WHERE username = '$addFriend')
AND reqTo = $userid";
if ( mysqli_num_rows(mysqli_query($conn, $query) ) == 1 ) {
$query = "DELETE FROM friendReq
WHERE initBy = (SELECT id FROM users WHERE username = '$addFriend')
AND reqTo = $userid";
mysqli_query($conn, $query);
$query = "INSERT INTO friends (user1, user2)
VALUES ($userid, (SELECT id FROM users WHERE username = '$addFriend') )";
mysqli_query($conn, $query);
die();
} else {
$query = "INSERT INTO friendReq (initBy, reqTo)
VALUES ($userid, (SELECT id FROM users WHERE username = '$addFriend') )";
mysqli_query($conn, $query);
die();
}
如果我的解释不是很明确,我道歉。有什么建议吗?
解决方案: 我不确定这是否是这里的SOP,但对于其他任何人来说,下面是我最终做的事情并且它有效。我确信要做一些效率改进(例如,从其他字符串构建各种查询字符串而不是重新输入其中的许多部分,以及使用multi_query),但对于一个简单的解决方案,希望有人发现这个使用方法:
{{1}}
答案 0 :(得分:1)
我会在没有实际代码的情况下回答这个问题,因为我很着急。你已经有了这个主要的设置,我喜欢你的布局。
尝试插入friendReq并获取插入的行数。如果插入了一行然后完成,如果插入了0行,则删除对方朋友请求并插入朋友。
这个解决方案不是100%的mysql,但也会使用php。
答案 1 :(得分:1)
我认为您会发现INSERT IGNORE
和DELETE IGNORE
语法更容易使用。
鉴于:
CREATE TABLE friendReq(
initBy
int(11),
reqTo
int(11),
独特的钥匙urel
(initBy
,reqTo
)
);
这允许您编写插入语句而不会弄乱EXISTS
子句:
INSERT IGNORE INTO friendReq (initBy, reqTo) VALUES ( 234, 901 );
INSERT IGNORE INTO friends (901, 234);
DELETE IGNORE FROM friendReq WHERE initBy=901 AND reqTo=234;
如果您向friendReq表添加done
列,则可以利用[on duplicate key update] [1语法]。然后更新标志列,而不必锁定删除。您可以推迟删除它们直到它们由cron进程处理,从而减少表上的读写争用:
INSERT INTO friendReq( initBy, reqTo, done) VALUES(234, 901, 0)
ON DUPLICATE KEY UPDATE done=1;