MySQL:如果不存在,插入一个表;如果是,请删除它并将其插入另一个表

时间:2013-07-19 22:20:55

标签: mysql

首先,我的基本结构如下。

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)上有一个唯一索引,因此,如果901234重新发送请求,则不会插入和添加额外行。凉。

我需要的是:如果234随后向901发送了请求,我不希望插入(initBy,reqTo) = (234, 901)(请注意,我已经设置了901234 1}}请求234234收到通知;这很好。我只是假设901忽略了请求并决定尝试手动添加(901,234)我简单的文字字段+添加朋友按钮)。相反,我希望它自动接受好友请求 - 也就是说,从friendReq删除friends并将该关系添加到INSERT INTO friendReq ( initBy, reqTo) VALUES ($userid, (SELECT id FROM users WHERE username = '$addFriend') ); 。这里没有个人资料页面 - 没有Facebook风格的“回复朋友请求”选项。这是一个简单的基于跟随者的应用程序,只需输入用户名并单击添加即可请求友谊。

我的功能SQL只是添加好友请求而不检查我刚刚描述的内容:

$addFriend

234来自给定用户输入的用户名以发送好友请求;请不要注意防止SQL注入,这只是我的简化示例。)

伪代码,假设901IF (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}}

2 个答案:

答案 0 :(得分:1)

我会在没有实际代码的情况下回答这个问题,因为我很着急。你已经有了这个主要的设置,我喜欢你的布局。

尝试插入friendReq并获取插入的行数。如果插入了一行然后完成,如果插入了0行,则删除对方朋友请求并插入朋友。

这个解决方案不是100%的mysql,但也会使用php。

答案 1 :(得分:1)

我认为您会发现INSERT IGNOREDELETE IGNORE语法更容易使用。

鉴于:     CREATE TABLE friendReq(       initBy int(11),       reqTo int(11),       独特的钥匙urelinitByreqTo)     );

这允许您编写插入语句而不会弄乱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;