V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
lukaz
V2EX  ›  问与答

该如何校正数据库中错误的数据

  •  
  •   lukaz · 2019-04-16 08:34:49 +08:00 via Android · 2421 次点击
    这是一个创建于 2082 天前的主题,其中的信息可能已经有所发展或是发生改变。
    当系统因某种异常( bug,宕机等)导致数据出现错误或未完全更新,要如何校正修复这些错误的数据呢?对于简单的系统来说,可能直接修改数据库来的简单直接,但如果情景稍微复杂一些,比如业务逻辑较为复杂,数据较多,数据库主从同步,缓存等,请教各位有什么好的方法来进行处理
    17 条回复    2019-04-16 13:37:23 +08:00
    dovme
        1
    dovme  
       2019-04-16 08:41:03 +08:00 via Android
    应该解决的不是为什么一有异常,数据库数据就错乱的问题吗?从源头解决会不会更好?
    xiaoyunwei2
        2
    xiaoyunwei2  
       2019-04-16 09:11:03 +08:00
    我来 丢给运维解决
    lukaz
        3
    lukaz  
    OP
       2019-04-16 09:21:38 +08:00
    @dovme 我指的是偶发的情形,不是说所有异常都会这样。而且有些情况是无法提前预知的,极端点的例子是机房突然停电。此处是想请教当数据错误已经出现了的情况下该如何处理。
    gamexg
        4
    gamexg  
       2019-04-16 10:16:40 +08:00   ❤️ 1
    @lukaz #3 事务就是用来解决断电等异常情况数据不统一的。

    已经这样了最简单的办法是写个程序遍历数据库修正了。

    另外一些内容也可以考虑防御是编程解决,正常流程执行时发现应该存在的数据不存在记录日志并补上(但是只有极少数情况合适)。
    Moorj
        5
    Moorj  
       2019-04-16 10:55:09 +08:00   ❤️ 2
    不要直接编辑主表内容,上缓存,我是自学的,不知道这个专业术语叫什么,我都叫他缓存

    举例:新建联系人,如果直接在主表上操作,如果断电或者宕机,就会产生一条垃圾信息(未编辑完成的记录)

    我会先在一个临时表里操作,然后点击确定的时候,自动运行脚本把临时表中的数据写入到主表中,然后清空临时表

    这样如果断电,也是临时表里有一条垃圾数据,主表不受影响,而临时表可以在每次开机的时候清空
    Moorj
        6
    Moorj  
       2019-04-16 10:56:26 +08:00
    类似于写作文先在草稿上写,写到满意了,点一个按钮,会有机器自动帮你誊写到宣纸上,以免出现意外情况浪费宣纸
    Moorj
        7
    Moorj  
       2019-04-16 10:57:38 +08:00
    如果是修改内容,也是一样的操作,把主表内容复制到临时表,修改完反写回去,这样还可以在反写的时候进行可靠性验证
    Xbluer
        8
    Xbluer  
       2019-04-16 11:07:53 +08:00 via iPhone
    @Moorj 你这个就是数据库事务处理过程吧,不用自己实现的
    Moorj
        9
    Moorj  
       2019-04-16 11:15:45 +08:00
    @Xbluer 事务处理只能是单记录,或者单字段,上临时表可以更自由一些
    huangqincan
        10
    huangqincan  
       2019-04-16 12:53:23 +08:00
    @Moorj 如果是在临时表插入主表的时候断电呢会不会造成同样的问题
    Moorj
        11
    Moorj  
       2019-04-16 13:08:24 +08:00 via Android
    @huangqincan 临时表转录主表,这个过程只有几毫秒,出问题的几率不大,并且最后一步是清空临时表,如果真的在这几毫秒断电,你还可以从临时表里找到未被清空的记录
    zhaishunqi
        12
    zhaishunqi  
       2019-04-16 13:17:49 +08:00
    不是应该所有的持久化操作都应该处于同一个事务内,当完成这个操作的时候,统一 submit 事务嘛?
    gamexg
        13
    gamexg  
       2019-04-16 13:19:47 +08:00
    @Moorj #9 事务没有单条记录单字段的限制。
    Moorj
        14
    Moorj  
       2019-04-16 13:22:41 +08:00
    @gamexg 学习了,看来专业的叫法,就是叫事务处理
    zhaishunqi
        15
    zhaishunqi  
       2019-04-16 13:24:56 +08:00   ❤️ 1
    @zhaishunqi 艾玛,习惯性 ctrl+回车就回复发出去了..
    理论上来说,从数据库拿到连接,开启一个事务以后,这一组操作都属于一个原子性的操作.
    在事务 submit 也就是纳秒-毫秒级别的,如果在这个事务提交的瞬间发生断电,基本上可以说比中彩票的几率小吧.
    如果碰到数据错误这样的情况,建议你看下你的系统是不是设计的有问题.
    silentstorm
        16
    silentstorm  
       2019-04-16 13:24:56 +08:00 via Android   ❤️ 1
    数据库的事务处理就是为了保证一致性的。即便是断电也有重做日志帮你恢复数据完整性。我觉得程序应该做到的就是保证关键业务处理在一个事务内完成,其他事情数据库做的肯定比你好。
    lukaz
        17
    lukaz  
    OP
       2019-04-16 13:37:23 +08:00
    @zhaishunqi @silentstorm 当业务逻辑需要跨系统时,无法放到一个事务内。另外,由于 bug 导致的数据错误还是难以避免的(可能是低级的计算错误或是底层框架缺陷而在测试的时候没有发现)。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   918 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:17 · PVG 06:17 · LAX 14:17 · JFK 17:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.