【问题标题】:Unique constraint, how to avoid duplicates唯一约束,如何避免重复
【发布时间】:2011-09-13 16:59:06
【问题描述】:

根据我之前的查询that post 我有一个看起来像这样的表:

|| *nid* || *language* ||
|| 8 || Chinese ||
|| 8 || Portuguese ||
|| 8 || German |

其中 'nid' 和 'language' 有唯一的约束。

通过此设置,我如何确保在尝试插入新行时不会有任何重复?

已编辑

我猜我应该尝试进行如下查询:

SELECT * FROM lang WHERE nid = $nid AND language = $lang

如果返回 FALSE,那么我知道我现在可以插入我的数据了。这是正确的吗?

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    通过创建唯一键来强制执行唯一约束:

    ALTER TABLE the_table
    ADD UNIQUE INDEX nid_language_unique (nid, language);
    

    此约束禁止两行具有相同的 nid 和语言。

    任何试图违反约束的查询都会失败。

    由于您想忽略错误(并且仍然中止查询),您可以使用INSERT IGNOREUPDATE IGNORE

    INSERT IGNORE INTO the_table (nid, language) VALUES (8, 'Chinese')
    /* row not inserted and no error */
    

    【讨论】:

    • 谢谢,这实际上是我所做的,虽然现在如果我添加一个重复的我得到一个错误,我想知道如何避免这种情况?我会更新我的问题以使其更清楚。
    • 如果您只想忽略错误(并且仍然不插入行),请使用 INSERT IGNORE。见mysql insert syntax
    【解决方案2】:

    如果您实际上已经在数据库中建立了唯一约束,那么 MySQL 将不允许您插入第二行。该语句将引发异常。您可以在代码中捕获并忽略它。如果您对是否添加了行不感兴趣,您可以在 MySQL INSERT INTO 命令中使用 IGNORE 键,该行将被添加(如果不存在)或者该命令将在没有错误的情况下完成。

    【讨论】:

      【解决方案3】:

      SELECT nid, language FROM lang WHERE nid = $nid AND language = $lang

      如果返回 FALSE,那么我知道我现在可以插入我的数据了。这是正确的吗?

      是的,但你需要写:

      $nid = mysql_real_escape_string($_POST['nid']);
      $lang = mysql_real_escape_string($_POST['lang']);
      $query = SELECT nid, language FROM lang WHERE nid = '$nid' AND language = '$lang'
      // notice the quotes                                ^    ^                ^     ^
      

      如果您忘记了这些,您的查询会报错(并面临 SQL 注入的风险)。

      如果你有唯一约束,你可以直接插入数据,因为 MySQL 会为你做上述测试。

      【讨论】:

      • 感谢 Johan 的注释,虽然我使用的是 drupal DB API,所以它可以处理所有这些东西 :)
      • @silk,如果你不使用 PDO,你仍然需要那些引号。
      【解决方案4】:

      您可以在代码中使用计数器(不是 SQL,而是用于使用 SQL 的计数器,如 PHP 或其他)

      你可以使用 MySQL 的 max 函数并添加一个(如 max(nid)+1 (但不记得 MySQL 的 max 函数))

      您可以使用 10 个字符的随机数(这样您出错的风险就会非常低)

      第一种和最后一种方式我用了很多次。

      如果您想确保没有重复,请使用您上一篇文章中的解决方案。像 UNIQUE 约束这样的东西会阻止你插入两次相同的 nid 或语言(因此,如果你不处理它,你的程序会崩溃)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-25
        相关资源
        最近更新 更多