MySQL删除群成员问题

来源:互联网 发布:ubuntu怎么安装apache 编辑:程序博客网 时间:2024/06/16 08:17
题目来源:http://bbs.csdn.net/topics/390885339
有三张表,第一张是用户表,第二张是群的信息,第三张是群的成员,如下所示
CREATE TABLE user_info (    user_id BIGINT(20) UNSIGNED NOT NULL,    PRIMARY KEY(user_id)); CREATE TABLE group_info (    group_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,    user_id BIGINT(20) UNSIGNED NOT NULL,    PRIMARY KEY(group_id),    FOREIGN KEY (user_id) REFERENCES user_info(user_id) ON DELETE CASCADE ON UPDATE CASCADE); CREATE TABLE group_member (    member_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,    group_id BIGINT(20) UNSIGNED NOT NULL,    user_id BIGINT(20) UNSIGNED NOT NULL,    PRIMARY KEY(member_id),    UNIQUE KEY(group_id, user_id),    FOREIGN KEY (user_id) REFERENCES user_info(user_id) ON DELETE CASCADE ON UPDATE CASCADE,    FOREIGN KEY (group_id) REFERENCES group_info(group_id) ON DELETE CASCADE ON UPDATE CASCADE-- 这里楼主写错了group_id);

怎么根据user_id和member_id来高效简洁的删除这条group_member记录?我写了好几天查询语句来实现的,赶紧不太好,我先是根据member_id来查找group_id,再根据group_id来获取user_id,再比较2个user_id是否相同来做删除。

在源出处,楼主写错了最后一个表的刷库语句,这里已纠正


这个问题,我们可以用存储过程来解决,我们的目的是删除group_member的某条记录,主键索引是member_id,如果member_id只是个普通成员,那么,我们可以直接删除member_id所在的记录,同时,这个member_id有可能跟user_id相同,也就是这个member_id可能是群主,那么,我们就要先判断member_id是否是群主,如果是,则要删除member_id创建的群,因为既然群主都没了,群肯定是要删除的。这里还有个坑,要注意,按照我们的正常逻辑,member_id可能创建了好几个群,但这个题目却不会,从何得知?请看创建群成员的刷库语句

UNIQUE KEY(group_id, user_id),

这个user_id是唯一索引,所以只能创建一个群。
另外再看刷库语句:
member_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,

这个语句是自增的,也就是说member_id跟user_id是不会相等的,所以题目才会说,根据user_id和member_id来删除group_member,而不是根据member_id来删除group_member,我们先来讨论把AUTO_INCREMENT去掉的情况,直接认为member_id跟user_id规则是一样的(题目不是这样要求的),也就是有可能相等,那么,情况就是玩家最多只能创建一个群,那么过程应该是下面这样子
CREATE PROCEDURE delmember()BEGINDECLARE t_member_id BIGINT(20) UNSIGNED;DECLARE t_user_id BIGINT(20) UNSIGNED;SET @memID = 10001;-- 改为要删除的玩家IDSELECT member_id, group_id, user_id INTO t_member_id, t_group_id, t_user_id FROM group_member WHERE member_id = @memID;IF t_member_id = t_user_id THEN-- 是群主DELETE FROM group_member where user_id = @memID AND group_id = t_group_id;DELETE FROM group_info where group_id = t_group_id;ELSEDELETE FROM group_member where member_id = @memID;  END IF;END

现在回答楼主的问题,正如上面所说的那样,要根据member_id跟user_id规则是不一样的,我们需要根据user_id和member_id来删除group_member,那么情况就不同了,要先找出群的ID,然后看下群主是否是user_id,如果是,则要删除整个群,如果不是直接删除member_id
那么过程就会是这样子:
CREATE PROCEDURE delmem()BEGINDECLARE t_group_id INT(20) UNSIGNED;DECLARE t_user_id INT(20) UNSIGNED;DECLARE s_user_id INT(20) UNSIGNED;SET @memID = 1;SELECT group_id, user_id INTO t_group_id, t_user_id FROM group_member WHERE member_id = @memID;-- 根据member_id找出user_idSELECT user_id INTO s_user_id FROM group_info WHERE user_id = t_user_id;-- 是否群主IF s_user_id <> 0 THEN-- 是群主DELETE FROM group_member WHERE group_id = t_group_id; -- 删除群成员
DELETE FROM group_info WHERE group_id = t_group_id;   -- 删除群信息ELSEDELETE FROM group_member WHERE member_id = @memID;END IF;END
其实,楼主完全可以把member_id设置成语user_id规则完全一样,这样可以避免很多问题,群成员都在同一张表,并且很好查找,而自增方式虽然可以省去一点空间,但却降低了可维护性

0 0