功能需求:
1、把 friend 和 friend_profile 表中的垃圾(符合一定条件)数据转移到 friend_rubbish 和 friend_profile_rubbish 表中
2、条件有可能较为复杂
非功能需求:
1、线上操作
2、千万级数据量
声明:俺不是DBA,只会写点简单的SQL……-_-! 高手、大牛、神人、耶稣、释迦摩尼……能指点就指点指点偶吧~~~~~~
写在前面的话:
1、“逐步”和“分批”都是“按uid分批”的意思(为啥要分批?因为非功能需求-.-),SQL中uid的范围是测试随便写的
2、“a.`login_num`<1 AND`reg_ip`='0.0.0.0'”也是随便写的条件(成为垃圾记录的具体条件)
3、friend_rubbish 和 friend_profile_rubbish 是根据 friend 和 friend_profile 的表结构新建来的
4、中间生成id_list.txt而没有纯SQL,是为了性能考虑,代价是需要人来手工参与(或写成工具脚本也可)
【方案一】
# 1、按条件逐步把 friend 表数据写入 friend_rubbish 表
INSERT INTO `friend_rubbish`
(
SELECT a.* FROM `friend` as a, `friend_profile` as b
WHERE a.`uid`=b.`uid`
AND a.`login_num`<1
AND b.`reg_ip`='0.0.0.0'
AND a.`uid`>0
AND a.`uid`<300
)
# 3、逐步把 friend_profile 表数据写入 friend_profile_rubbish 表(直接参照 friend_rubbish 表中记录)
INSERT INTO `friend_profile_rubbish`
(
SELECT * FROM `friend_profile`
WHERE `uid` IN
(
SELECT `uid` FROM `friend_rubbish`
WHERE `uid`>0 AND `uid`<300
)
)
# 4、分批准备好所有要删除记录的id_list
SELECT `uid` INTO OUTFILE '/tmp/id_list.txt'
LINES TERMINATED BY ','
FROM `friend_rubbish`
WHERE `uid`>0 AND `uid`<300
# 5、逐步清理 friend 和 friend_profile 表
DELETE FROM `friend` WHERE `uid` IN (【一批id_list】)
DELETE FROM `friend_profile` WHERE `uid` IN (【一批id_list】)
貌似有些复杂。。。又想了个方案二。。。
【方案二】
# 1、friend 和 friend_profile 表新增字段flag=0
# 2、分批准备好所有要清理的记录的id_list
SELECT a.`uid` INTO OUTFILE '/tmp/id_list.txt'
LINES TERMINATED BY ','
FROM `friend` as a, `friend_profile` as b
WHERE a.`uid`=b.`uid`
AND a.`login_num`<1
AND b.`reg_ip`='0.0.0.0'
AND a.`uid`>0
AND a.`uid`<300
# 3、逐步置 friend 和 friend_profile 表中垃圾记录flag=1
UPDATE `friend` SET `flag`=1 WHERE `uid` IN (【一批id_list】)
UPDATE `friend_profile` SET `flag`=1 WHERE `uid` IN (【一批id_list】)
# 4、逐步把 friend 和 friend_profile 表垃圾数据写入 friend_rubbish 和 friend_profile_rubbish 表
INSERT INTO `friend_rubbish`
(
SELECT * FROM `friend`
WHERE `flag`=1 AND `uid`>0 AND `uid`<300
)
INSERT INTO `friend_profile_rubbish`
(
SELECT * FROM `friend_profile`
WHERE `flag`=1 AND `uid`>0 AND `uid`<300
)
# 5、逐步删除 friend 和 friend_profile 表中flag=1的垃圾记录
DELETE FROM `friend` WHERE `flag`=1 AND `uid`>0 AND `uid`<300
DELETE FROM `friend_profile` WHERE `flag`=1 AND `uid`>0 AND `uid`<300
# 6、删除friend 和 friend_profile 表中flag字段
等等!貌似可以优化,flag字段好像很多余的说。。。
【方案三】
# 1、分批准备好所有要清理的记录的id_list
SELECT a.`uid` INTO OUTFILE '/tmp/id_list.txt'
LINES TERMINATED BY ','
FROM `friend` as a, `friend_profile` as b
WHERE a.`uid`=b.`uid`
AND a.`login_num`<1
AND b.`reg_ip`='0.0.0.0'
AND a.`uid`>0
AND a.`uid`<300
# 2、分批把 friend 和 friend_profile 表垃圾数据写入 friend_rubbish 和 friend_profile_rubbish 表
INSERT INTO `friend_rubbish`
(
SELECT * FROM `friend` WHERE `uid` IN (【一批id_list】)
)
INSERT INTO `friend_profile_rubbish`
(
SELECT * FROM `friend_profile` WHERE `uid` IN (【一批id_list】)
)
# 3、分批删除 friend 和 friend_profile 表中的垃圾记录
DELETE FROM `friend` WHERE `uid` IN (【一批id_list】)
DELETE FROM `friend_profile` WHERE `uid` IN (【一批id_list】)
厄……还是这个简单明了~