我有一个应用程序,可以生成多个随机数并使用以下代码将其插入到 MySQL 数据库中:
fielda 是主键,fieldb 是 12 位随机键,要求必须唯一,并在数据库中设置为唯一。
$datafields = array('fielda', 'fieldb', 'created_on');
$data = array(value1a, value1b, 'now()',value2a, value2b, 'now()' ....valueNa, valueNb, 'now()');
其中 N(和变量 $N)是总行数,表中每次插入的行数通常约为 100,000 到一百万
function placeholders($text, $count=0, $separator=","){
$result = array();
if($count > 0){
for($x=0; $x<$count; $x++){
$result[] = $text;
}
}
return implode($separator, $result);
}
$pdo->beginTransaction(); // also helps speed up your inserts.
for($i=0;$i<$N;$i++){
$question_marks[] = '(' . placeholders('?', 7) . ')';
}
$sql = "INSERT INTO code (" . implode(",", $datafields ) . ") VALUES " . implode(',', $question_marks);
$stmt = $this->db->prepare($sql);
try {
$stmt->execute($data);
} catch (PDOException $e){
echo $e->getMessage();
}
$pdo->commit();
我对上述内容有以下疑问:
就我而言,我一次插入接近 100000 行。如果我理解正确并形成了我运行的实验,即使查询中的一行有 fieldb 或 fielda 的重复项,整个查询也会失败。
1) 是否可以更改此行为并至少插入那些不重复的行,并返回行数和找到重复项的字段值,以便仅重新生成这些行。我想这样做是为了避免在 PHP 中检查我生成的每个代码(如果它存在于数据库中)或生成的新代码集。我在每个实例中插入 100000 到 100 万行,并且这个数据库只会变得更大。我用来在插入之前搜索重复值的 array_flip、in_array 等操作在大数据库中耗尽内存并导致应用程序崩溃,因此我想避免 PHP 中的重复检查,而是按照上面的方法执行。
2)如果上述情况可行,我希望 MySQl 返回所有成功插入的行,以便我可以将其输出给用户。
最佳答案
您需要确保插入在 MySQL 级别失败。为此,您必须使随机数属于唯一索引,例如:
CREATE TABLE code (
-- [...]
UNIQUE INDEX fieldb_unique (fieldb)
);
这具有确保数据完整性的额外好处。
一旦获得此信息,您将看到失败的插入将抛出 PDOException
。为了增加稳健性,您应该检查 MySQL error code 是否是1062
:
Error: 1062 SQLSTATE: 23000 (ER_DUP_ENTRY)
Message: Duplicate entry '%s' for key %d
The message returned with this error uses the format string for ER_DUP_ENTRY_WITH_KEY_NAME.
list($sqlstate, $mysql_code, $message) = $stmt->errorInfo();
if ($mysql_code==1062) {
}
关于php - 当 PHP 在单个查询中插入多个值由于重复而失败时插入非重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40419824/