2013-07-16 2 views
5

Возможно, этот вопрос уже задан, но я не знаю, как его искать:Должен ли я проверить уникальное ограничение с помощью php?

У меня есть клиенты postgres-table «клиенты», и каждый клиент имеет свое собственное уникальное имя. Чтобы достичь этого, я добавил уникальное ограничение в этот столбец.

Доступ к таблице с php.

Когда пользователь пытается создать нового клиента с уже зарегистрированным именем, база данных говорит «Нарушение ограничения целостности», а php выдает ошибку.

Что я хочу сделать, это показать ошибку в поле ввода html: «Имя клиента уже принято», когда это произойдет.

Мой вопрос в том, как я должен это делать.

Должен ли я поймать PDO-исключение, проверьте, является ли код ошибки «УНИКАЛЬНЫМ НАРУШЕНИЕМ», а не отображает сообщение в соответствии с Exception-Message, или я должен проверять наличие дубликатов имен с дополнительным заявлением до того, попробуйте вставить новую строку?

Что лучше? Создание еще одного sql-оператора, или поиск и анализ кодов ошибок.

EDIT: Я использую транзакции, и я предпочитаю исключение для отката. Вопрос в том, должен ли я отфильтровывать уникальные нарушения, чтобы они не приводили к откату.

EDIT2: Если я использую исключение-метод, я должен был бы проанализировать исключение-сообщение для того, чтобы гарантировать, что единственное ограничение, на самом деле принадлежит «имя» -column.

Это все, что я получаю от за исключением:

["23505",7,"FEHLER: doppelter Schlüsselwert verletzt Unique-Constraint <customers_name_unique>\nDETAIL: Schlüssel <(name)=(test)> existiert bereits."] 

Единственный способ получить информацию о столбце, чтобы проверить, если «customers_name_unique» существует (это название уникального-ограничения).

Но, как вы можете видеть, сообщение находится на немецком языке, поэтому выход зависит от системы/может быть изменен.

+0

Возможно, вам стоит взглянуть на: http://stackoverflow.com/questions/7719039/php-duplicate-checking-before-insert – jmarceli

ответ

2

Вопрос здесь не совсем, но я отвечу вам.

Исключения - это ситуации, когда происходит нечто исключительное. Это означает, что вы не должны использовать их для обработки ситуации, которая может произойти часто. Если вы это сделаете, это похоже на код GOTO. Лучшее решение состоит в том, чтобы проверить предысторию, если есть какая-либо повторяющаяся строка. Однако решение с исключениями проще, поэтому вам нужно решить, хотите ли вы что-то работать или хотите, чтобы что-то работало так, как должно быть.

+1

Я не согласен. Лучше иметь нормальный поток на «высшем» уровне, а затем перехватывать исключения. Это сделает более быстрый код, так как если вы не на более низком уровне, вам придется повторить ту же проверку. Если эта проверка является тяжелой cpu, вы можете сделать действительно неэффективное приложение, если у вас есть несколько уровней (услуги/хранение/классы в этом случае считаются уровнями) –

+1

Исключения могут вызвать множество проблем при отладке. Кроме того, исключения оставляют объекты в несогласованном состоянии. Если вы используете их слишком часто, у вас может быть много ошибок, которые трудно отслеживать. Obviosly вы можете использовать, наконец, блок, который был сделан для обработки таких ситуаций, но не все знают об этом. Даже знаменитый Линус Торвальдс сказал, что исключения - это дерьмо. Кроме того, google в google go подал в отставку из проверки исключений в google почему. Исключения могут быть также очень дорогими с точки зрения производительности, если вы не используете их с умом. Это ваше право не согласиться, но это не значит, что вы правы, P – Robert

0

Ошибки - это плохо, я бы предпочел проверить, нет ли имени, прежде чем добавлять его. Ну, вы все равно должны проверить, нет ли ошибок при вставке, во избежание ситуации, когда параллельные скрипты пытаются вставить одно и то же имя (есть время между проверкой наличия и вставки, поскольку это не транзакция).

1

Я бы выбрал исключение, потому что (благодаря параллелизму), которое может случиться в любом случае, даже если вы предварительно проверите дополнительный запрос.

0

На SAVE проверьте, существует ли (простое поле, в вашем случае: столбец ограничений). Если утвердительно - сообщите пользователю о дублировании уведомления. Но не заставляйте сервер БД возвращать вам исключения.

5

Вы должны поймать исключение PDO.

Это быстрее, если база данных не удалась, чем искать и посмотреть, существует ли запись.

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

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

+0

Проблема согласованности не может появиться, так как я не удалю ограничение проверки из базы данных. Единственная проблема заключалась бы в том, что в редком случае состояния гонки пользователь получил бы сообщение «Неизвестная ошибка» вместо «Дублируемое имя клиента» – maja

+0

, это хорошо сохраняет один 'count (*)', но i есть сомнения, поскольку он использует транснациональный механизм хранения, может потребоваться действие отката, стоимость которого меньше, чем 'count (*)' раньше? –

+0

«check-constraint» - это всего лишь обходной путь (если вы не используете, если для чего-то еще) для части проблемы. Но я бы предложил реализовать как можно больше логики при обработке ошибок, а затем поговорить с базой данных как можно чаще (например, пропустить инструкцию для проверки уникального индекса) –

Смежные вопросы