按条件迁移数据[MySQL]

功能需求:

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】) 

 

厄……还是这个简单明了~

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值