前几天脑子犯抽,把数据库用户表的字段update错误,mysql自身没法回复的情况下(刚执行完我就意识到了,所以没法备份),只能根据本身字段的一些信息进行数据恢复,下面详细说一下我辛苦的数据恢复历程
用户表:存储一些用户信息及用户状态,用户状态分为6种,用checkstatus字段存储(0普通用户,1待认证用户,2认证用户,3预备达人,4普通达人,5vip达人)。字段passtime表示用户成为认证用户的时间,字段preparetime表示用户成为预备达人的时间,字段darentime表示用户成为普通达人的时间,字段viptime表示用户成为vip达人的时间。也就是说如果一个用户现在的状态是预备达人,则它的passtime preparetime都有值,而darentime和viptime都为0.现在我将所有的checkstatus都update成了1(罪过罪过)
如果只是这样简单的话我直接通过,相应认证时间的字段就可以判断用户的状态,比如如果一个用户有成为认证时间,有成为预备达人时间,没有成为普通大人和成为vip达人时间那他肯定是预备达人。但这里有一个用户升降级的操作,也就是说用户可以被管理员降级,也可以被升级。幸好我们有升降级的操作log。log表中有每次升降级的操作时间createtime,以及每次操作的状态opetype(操作类型 0 添加 1 修改 2 删除 3 认证 4 撤销认证 5 升为预备达人 6 升为普通达人 7 升为VIP达人 8 降为预备达人 9 降为普通达人).此时此刻我真是爱死了当初设计数据库的同学。
截至目前,我们就可以用上面这些信息进行数据恢复了。
所有用户中绝大部分是普通用户,只有2000多条非普通用户,现在我将所有非普通用户全部修改成了待认证用户。也就是说现在我们应该从认证用户开始恢复
思路是这样的:首先我们根据user表中对应的时间将用户状态先进行一个初步的修改,也就是说如果用户的passtime>0,我就讲用户状态修改成2.然后在判断如果用户的preparetime>0就将用户状态修改成3,一次类推,这样在不考虑用户升降级的情况下恢复用户的状态是没错的。
其次,因为用户的每次升降级都会存储在log表中,此时,我们循环所有用户,将搜索出用户在log表中的最近的一条数据,查看用户的状态,然后和相应的时间进行比较,比如:如果用户log表中的操作是8,8是降为预备达人,则如果它的操作时间createtime大于darentime的话,说明用户是先升为普通大人然后降级的,如果操作时间createtime<darentime说明用户是升级成预备达人然后降级,最后在升级成为普通达人。这里还有一个问题,就是用户可以连续降级,用户降级为预备达人,我们将createtime于darentime时间进行对比,用户此时也有可能是又vip->daren->prepare的,所以这时我们应该在在和viptime比较一下。
如果有同学想仔细了解的话,请联系我,我会将详细的代码和数据库信息贴出来