У меня есть таблица 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 позаботиться о проверке данных.