【问题标题】:MySQL Insert: Test first?MySQL 插入:先测试?
【发布时间】:2009-01-13 18:16:10
【问题描述】:

例如,将记录插入到具有唯一索引的表中时,最好先进行测试吗? 例如,

$mysqli->query('SELECT email FROM tblUser WHERE email = 'foo@bar.org');

然后确保返回 0 行,然后插入?

$mysqli->query('INSERT INTO tblUser ...');

或者,如果有重复条目,最好跳过测试并处理错误?

谢谢!

【问题讨论】:

  • 澄清:值必须是唯一的并且表具有唯一的索引——尝试插入重复的键会导致错误。谢谢!

标签: php mysql database


【解决方案1】:

最好插入和处理任何重复的键错误。

原因是,如果您先进行测试,其他一些客户端仍然可以在您的测试和插入之间的短暂时刻插入该值。所以无论如何你都需要处理错误。

【讨论】:

  • "INSERT INTO table (name,email) VALUES ('bob','bob@example.com') ON DUPLICATE KEY UPDATE ..."
  • 是的,我知道如何使用 ON DUPLICATE KEY 语法,但 OP 并没有说他想在出现重复时更新。
【解决方案2】:

广义上讲,有三种方法可以通过单个查询来处理这种情况(更少的查询通常是一件好事),但它们都不是通用的“最佳方法”。您应该使用哪种取决于您的需求。

正如您提到的,第一个是盲目地运行INSERT … 并处理PHP 的任何错误。当重复键表示程序问题(软件中的错误,用户尝试注册已使用的名称等)时,这是最好的方法,因为它允许您在提交数据库更新之前执行其他操作.

其次,有INSERT IGNORE … 语法。我倾向于将此称为最不常用的方法,因为如果密钥已经存在,它会完全丢弃您的INSERT。当一行(或多行)之前可能已添加或未添加到表中但已知数据未更改时,主要有用。

最后,您可以使用INSERT … ON DUPLICATE KEY UPDATE … 语句。这些可能会变得相当冗长,但非常方便,因为它们允许您将数据插入表中,而不必担心是否存在旧数据。如果是这样,则更新现有行。如果没有,则插入一个新的。无论哪种方式,您的表格都会有最新的可用数据。

【讨论】:

    【解决方案3】:

    如果您想忽略创建具有另一行的键值的行的插入,MySQL 支持插入忽略。

    只要确保 tblUser 中的电子邮件有一个唯一索引并执行

    $mysqli->query('INSERT IGNORE INTO tblUser ...');
    

    【讨论】:

      【解决方案4】:

      这取决于您是否要确保插入的值不存在。如果您在文件上有一个唯一键,那么不要创建重复键(这将引发错误),这一点很重要。很多时候您也想测试是否存在记录,如果存在则返回记录的主键,以便您可以更新记录,如果不存在则插入记录。

      但是,如果您没有唯一键并且不关心信息是否在字段或字段组合中重复,则没有必要并且可以节省一点时间。只是视情况而定。

      HTH

      【讨论】:

        【解决方案5】:

        通常取决于适用的数据复制规则。

        在您的示例中,您的应用是否允许多个用户拥有相同的电子邮件地址?如果没有,那么您需要执行该检查。

        【讨论】:

        • 或者将电子邮件列定义为唯一键。然后您可以运行 INSERT 而无需先检查。错误消息将指出哪一列失败。
        【解决方案6】:

        你肯定想先测试,你可能想测试一些东西,这样你就可以告诉用户出了什么问题。

        例如,我刚刚完成了一项用户需要唯一用户名和唯一电子邮件地址的工作。

        【讨论】:

          猜你喜欢
          • 2020-01-03
          • 2021-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-19
          相关资源
          最近更新 更多