首页 > 解决方案 > 我应该使用 SELECT 还是重复唯一键错误来检查用户和/或电子邮件是否存在?

问题描述

与一些同事交谈时,他们说我们不应该使用 SELECT 检查唯一键是否已经存在。必须使用数据库返回的约束错误来完成检查。

我有以下情况:

  1. 我需要向用户返回一条消息,告知用户名或电子邮件是否已注册(用户名和电子邮件是唯一键)。

  2. 我需要生成密码哈希以插入新用户。

如果我根据数据库返回的约束违规错误验证用户名和电子邮件(两者都是唯一键),我不知道它是用户名还是已注册的电子邮件。

如果我只是在检查用户名和电子邮件是否存在之前将用户插入数据库,并且其中一个或另一个已经存在,那么我将浪费不必要的处理时间来生成密码哈希。

在这种情况下,最好的方法是什么?如果在 INSERT 之前使用 SELECT,则考虑数据完整性。

标签: postgresqlvalidationconstraints

解决方案


你可以这样进行:

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;

如果表的 afillfactor小于 100,并且没有索引password(不应该有),这可能是一个有效的 HOT 更新。

但我会衡量哈希创建是否比额外的数据库往返更昂贵......


推荐阅读