我经常需要阻止查询在电子邮件等值存在时执行。
到现在为止我搜索了这样的值:
$checkemailexist = $X['db']->prepare("SELECT uid FROM userdata WHERE uid = :uid LIMIT 1");
$checkemailexist->execute(array(
':uid'=>$uid
));
if(empty($checkemailexist)){
INSERT QUERY ..
}
...
在具有许多行的大型数据库上存在问题,即使在varchar上进行字符串搜索也会占用大量的性能和时间。
所以我使uid专栏独一无二,尝试过类似的东西:
try{
$insertuser = $X['dbh']->prepare("
INSERT INTO user (uid) VALUES (:uid)
");
$insertuser->execute(array(
':uid'=> $mail
));
} catch (PDOException $e) {
header("Location: ...");
exit();
}
它工作正常,但性能甚至可能更差?
在使uid列成为[唯一]索引之后,您可以更快地完成所有查询。 SELECT或INSERT这两个查询都必须检查索引,并且它们将同时执行它们。
向用于搜索的列添加索引是您问题的真正答案。至于是否使用选择查询或在插入期间捕获异常是一个品味问题。
但是,你的第二个例子是错误的。你不应该以同样的方式处理每个PDOException,而只是处理与这种情况相关的特定异常,因为它在我的PDO tutorial中显示。
最好的方法是保留唯一索引,但在查询中添加关键字IGNORE,然后检查受影响的行数
$insertuser = $X['dbh']->prepare("INSERT IGNORE INTO user (uid) VALUES (:uid)");
$insertuser->execute(['uid'=> $mail]));
if (!$insertuser->numRows()) {
header("Location: ...");
exit();
}
添加IGNORE会抑制唯一索引错误,您只需检查受影响的行数即可检查此类值是否已存在