[php] 如何在MySQL中插入“如果不存在”?


Answers

INSERT INTO `table` (value1, value2) 
SELECT 'stuff for value1', 'stuff for value2' FROM `table` 
WHERE NOT EXISTS (SELECT * FROM `table` 
      WHERE value1='stuff for value1' AND value2='stuff for value2') 
LIMIT 1 

或者,外部SELECT语句可以引用DUAL以处理表初始为空的情况:

INSERT INTO `table` (value1, value2) 
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM `table` 
      WHERE value1='stuff for value1' AND value2='stuff for value2') 
LIMIT 1 
Question

我开始用google搜索,并找到了article谈论互斥表的article

我有一张约有1400万条记录的表格。 如果我想以相同的格式添加更多的数据,有没有办法确保我想插入的记录不存在,而不使用一对查询(即,一个查询来检查,一个要插入的结果集是空)?

一个字段上的unique约束是否保证insert将会失败,如果它已经在那里?

似乎只有一个约束,当我通过php发布插入时,脚本就会呱呱叫。




这是一个PHP函数,只有当表中所有指定的列值都不存在时才会插入一行。

  • 如果其中一列不同,则该行将被添加。

  • 如果表格为空,则该行将被添加。

  • 如果某行存在所有指定列都具有指定值的行,则不会添加该行。

    function insert_unique($table, $vars)
    {
      if (count($vars)) {
        $table = mysql_real_escape_string($table);
        $vars = array_map('mysql_real_escape_string', $vars);
    
        $req = "INSERT INTO `$table` (`". join('`, `', array_keys($vars)) ."`) ";
        $req .= "SELECT '". join("', '", $vars) ."' FROM DUAL ";
        $req .= "WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE ";
    
        foreach ($vars AS $col => $val)
          $req .= "`$col`='$val' AND ";
    
        $req = substr($req, 0, -5) . ") LIMIT 1";
    
        $res = mysql_query($req) OR die();
        return mysql_insert_id();
      }
    
      return False;
    }
    

用法示例:

<?php
insert_unique('mytable', array(
  'mycolumn1' => 'myvalue1',
  'mycolumn2' => 'myvalue2',
  'mycolumn3' => 'myvalue3'
  )
);
?>



如果可以接受例外,任何简单的约束都应该完成这项工作。 例子 :

  • 主键如果不是代孕的话
  • 列上的唯一约束
  • 多列唯一约束

对不起,这看起来似乎很简单。 我知道它与您与我们分享的链接看起来很糟糕。 ;-(

但我永远无法给出这个答案,因为它似乎满足你的需要。 (如果没有,它可能会触发你更新你的需求,这也将是“一件好事”(TM))。

已编辑 :如果插入操作会破坏数据库唯一性约束,则会在驱动程序传递的数据库级别引发异常。 它肯定会停止你的脚本,失败。 PHP中必须能够解决这个问题......




有几个答案涵盖了如何解决这个问题,如果你有一个UNIQUE索引,你可以用ON DUPLICATE KEYINSERT IGNORE 。 情况并非总是如此,因为UNIQUE具有长度限制(1000字节),您可能无法更改该限制。 例如,我不得不在WordPress中使用元数据( wp_postmeta )。

我终于用两个查询解决了它:

UPDATE wp_postmeta SET meta_value = ? WHERE meta_key = ? AND post_id = ?;
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) SELECT DISTINCT ?, ?, ? FROM wp_postmeta WHERE NOT EXISTS(SELECT * FROM wp_postmeta WHERE meta_key = ? AND post_id = ?);

当有问题的数据集不存在时,查询1是一个常规的UPDATE查询,不起作用。 查询2是一个INSERT ,它依赖于NOT EXISTS ,即INSERT只在数据集不存在时执行。









Links