Должен ли я использовать SELECT или повторяющуюся ошибку уникального ключа, чтобы проверить, существует ли пользователь и / или электронная почта? - PullRequest
0 голосов
/ 06 февраля 2019

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

У меня есть следующий сценарий:

  1. Мне нужно вернуть сообщение пользователю, сообщающее, если имя пользователя ИЛИ ИЛИадрес электронной почты уже зарегистрирован (имя пользователя и адрес электронной почты - уникальный ключ).

  2. Мне нужно создать хэш пароля для вставки нового пользователя.

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

Если я просто ВСТАВЛЮпользователь в базу данных, прежде чем проверять наличие имени пользователя и адреса электронной почты, и тот или другой уже существует, я бы потратил лишнее время на обработку для создания хэша пароля.

Какой подход был бы лучшим вэтот случай?Учитывая целостность данных при использовании SELECT перед INSERT.

1 Ответ

0 голосов
/ 06 февраля 2019

Вы могли бы действовать следующим образом:

INSERT INTO users (username, email, password)
VALUES ('newuser', 'newemail', NULL)
ON CONFLICT (username) DO NOTHING
RETURNING id;

Если вы получили пустой результат, произошло столкновение с существующим именем пользователя.

Если вы получили нарушение ограничения, былоконфликт с существующим адресом электронной почты.

Если вы получаете id, вернитесь, установите пароль:

UPDATE users
SET password = 'newpassword'
WHERE id = v_id;

Если таблица имеет fillfactor меньше чем100, и нет индекса password (которого не должно быть), это могло бы быть эффективным обновлением HOT.

Но я бы измерил, если создание хэша обходится дороже, чем дополнительная обход туда и обратно...

...