проверить дублируемую запись и использовать результат PDO errorInfo

У меня есть таблица MySQL, в которой есть поле для адресов электронной почты, которое определено как уникальное. В этом примере предположим, что вся моя форма позволяет пользователю вставлять свой адрес электронной почты в таблицу.

Поскольку поле электронной почты является уникальным, запрос должен быть неудачным, если он пытается дважды ввести один и тот же адрес электронной почты. Мне любопытно компромисс между двумя сценариями:

1) Запустите быстрый SELECT перед выполнением вставки. Если выбор возвращает результаты, сообщите об этом пользователю и не запустите INSERT .

2) Запустите INSERT и проверьте наличие ошибки повторного ввода

 // snippet uses PDO if (!$prep->execute($values)) { $err = $prep->errorInfo(); if (isset($err[1])) { // 1062 - Duplicate entry if ($err[1] == 1062) echo 'This email already exists.'; } } 

Кроме того, предположим, что это нормальное использование, что означает, что дублирующие записи должны быть минимальными. Поэтому в первом сценарии у вас, очевидно, есть накладные расходы на выполнение дополнительного запроса для каждой вставки, тогда как во втором вы полагаетесь на обработку ошибок.

Кроме того, мне любопытно слышать мысли о стиле кодирования. Мое сердце говорит: «Будь защитником! Проверьте данные перед вставкой! ' в то время как мой мозг говорит: «Хм, возможно, лучше, чтобы MySQL позаботился о проверке данных для вас».

EDIT. Обратите внимание, что это не вопрос «Как это сделать», а вопрос «Почему я должен делать это конкретным образом». Небольшой фрагмент кода, который я включил в работу, но то, что мне интересно, – лучший способ решить проблему.

Статус проверки INSERT + должен быть лучше. С помощью SELECT + INSERT вы можете иметь другой поток, вставляющий одно и то же значение между SELECT и INSERT , что означает, что вам нужно будет также обернуть эти два оператора в блокировку таблицы.

В вашей кодировке легко ошибиться на стороне слишком большой защиты. У Python есть высказывание, что «легче просить прощения, чем просить разрешения», и эта философия не является специфичной для Python.

Вы можете выполнить это с помощью блока catch try:

 try { $prep->execute($values); // do other things if successfully inserted } catch (PDOException $e) { if ($e->errorInfo[1] == 1062) { // duplicate entry, do something else } else { // an error other than duplicate entry occurred } } 

Вы также можете изучить альтернативы, такие как «INSERT IGNORE» и «INSERT … ON DUPLICATE KEY UPDATE» – хотя я думаю, что они являются специфичными для MySQL и будут противоречить переносимости использования PDO, если это вас беспокоит ,

Изменить: Чтобы более формально ответить на ваш вопрос, для меня решение № 1 (защитный программист) в полном объеме эффективно устраняет точку единственного ограничения в первую очередь. Поэтому я бы согласился с вашей мыслью позволить MySQL позаботиться о проверке данных.