【问题标题】:Should check for duplicate or catch exception from database?应该检查数据库中的重复或捕获异常吗?
【发布时间】:2011-11-18 13:32:47
【问题描述】:

当我们使用数据库编程时(例如在Java和MySql中),我们应该在插入之前检查重复条目,还是应该插入并捕获重复的异常以向用户发出警报?

在我看来,如果我们进行检查,并且如果没有重复条目,我们将插入该条目,并且数据库引擎本身会再次检查重复的主键。听起来很浪费时间。

你觉得怎么样?

【问题讨论】:

    标签: database algorithm


    【解决方案1】:

    如果您检查客户端(在您的程序中)是否存在重复键,则需要查询数据库。由于如果已经存在具有相同PK的记录,则插入查询将返回错误,因此在发送插入语句之前无需执行此检查。
    您可以插入、捕获异常/错误代码(我不确定它是否会在 java 中给出异常,或返回错误代码),然后提醒用户。

    编辑 -
    如果有许多用户使用同一个数据库,那么如果您检查然后插入,主要问题是其他人可以在您检查之后但在您插入之前插入相同的密钥。如果您想这样做,则需要使用事务 - 检查和插入必须都发生在同一个事务中。您可以阅读 MySQL 事务here

    【讨论】:

    • 我也是这么想的!谢了!
    • 这只是偶然的正确答案。 check-then-insert 的 main 问题是一种竞争条件:其他人可以插入相同的密钥 after 您检查但 before 您插入。为了使 check-then-insert 可靠,检查和插入必须同时发生在同一个事务中,但您根本没有提到事务。 -1,直到你解决这个问题。
    • @j_random_hacker:感谢您的意见。 :) 我已按照建议修改了我的答案。当我回答这个问题时,我没有(显然)关于交易。
    【解决方案2】:

    浪费时间不是您最关心的问题。

    我假设不止一个用户(或进程)可以在任何时候访问您的数据库;如果您完全依赖“预插入”检查,则其他用户可能会在您的检查和您的插入语句。

    因此,您应该始终以用户友好的方式处理“重复键”错误。

    然而,当前的用户界面似乎兼具两者——在将数据提交到数据库之前验证数据,很好地处理数据完整性错误。

    这样做有几个原因 - 一方面是用户友好,但效率和性能也很重要。在大多数应用程序中,数据库是一种“稀缺资源”,依赖错误进行应用程序逻辑代价高昂且效率低下。

    因此,如果您只是将一条记录插入到单个表中,则使用“重复键”异常是可以的。如果您要插入多条记录,使用外键等插入多个表,并且(希望)进行一两个事务,则使用异常会很昂贵,并且可能会产生大量“回滚”工作。

    在 MySQL 上,对事务的不同支持会加剧这种情况(取决于您使用的版本和存储选项)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多