我有一个生成多个随机数的应用程序,并使用以下代码在MySQL数据库中插入相同的代码:
fielda是主键,fieldb是12位随机密钥,必须是唯一的,并且在DB中设置为唯一。
$datafields = array('fielda', 'fieldb', 'created_on');
$data = array(value1a, value1b, 'now()',value2a, value2b, 'now()' ....valueNa, valueNb, 'now()');
其中N(和变量$ N)是总行数,对于表中的每个插入,通常为100,000到100万
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,如果它存在于DB或生成的新代码集中。我在每个实例插入100000到100万行的任何地方,这个数据库只会变大。我用于在插入之前搜索重复值的array_flip,in_array等操作是使用大型数据库耗尽内存并导致应用程序崩溃,因此我想避免在PHP中重复检查,而是如上所述。 / p>
2)如果上述情况可能,我希望MySQl返回成功插入的所有行,以便我可以将其输出给用户。
答案 0 :(得分:0)
您需要确保在MySQL级别插入失败。为此,您必须使随机数属于唯一索引,例如:
CREATE TABLE code (
-- [...]
UNIQUE INDEX fieldb_unique (fieldb)
);
这具有确保数据完整性的额外好处。
一旦你有了这个,你会看到失败的插入会抛出PDOException
。为了增强稳健性,您应该检查MySQL error code是否为1062
:
错误:1062 SQLSTATE:23000(ER_DUP_ENTRY)
消息:密钥%d的重复条目'%s'
使用此错误返回的消息使用格式字符串 ER_DUP_ENTRY_WITH_KEY_NAME。
list($sqlstate, $mysql_code, $message) = $stmt->errorInfo();
if ($mysql_code==1062) {
}