我在Java中有一个简单的MVC应用程序,db(Postgres)和表名为users的用户具有以下列:
name,email,age,birthday
其中一项功能:注册时,用户应提供姓名和电子邮件。两个字段在表格中必须是唯一的(唯一名称和唯一电子邮件)
要验证用户输入,请使用以下sql
select * from users where email = ? or name = ?
如果查询返回一列,则用户的数据不是唯一的。
在JavaMelody
的帮助下,我注意到这个查询是最长的查询(11毫秒)我怎样才能加快这个问题?
顺便说一句
从官方文档来看,Postgres不建议创建包含多列的索引。
EDIT() 在答案中我已经看到我应该添加唯一约束添加捕获异常如果存在,但使用我的查询我可以检查哪个参数不唯一
示例:
public Optional<String> isUnuque(final Users user) {
final Users dbUser = this.repository.findByEmailOrName(user.getEmail(), user.getName(),user.getSteamId());
if (dbUser != null) {
if (user.getEmail().equals(dbUser.getEmail())) {
return Optional.of("Email is not unique");
}else if(user.getName().equals(dbUser.getName())) {
return Optional.of("Name is not unique");
}
}
return Optional.empty();
}
答案 0 :(得分:2)
您可以对数据库中的字段名称和电子邮件设置唯一约束。然后,当您尝试插入时,如果它不唯一,则会返回错误。
答案 1 :(得分:0)
使用查询来检查特定记录是否存在不会是优化的解决方案,因为将来会增加记录的数量。而不是为这两个字段添加唯一的约束,然后在代码中捕获异常。 / p>
如果您使用的是spring,则可以捕获org.springframework.dao.DataIntegrityViolationException
try {
some_repository.save(new User(..));
}
catch (DataIntegrityViolationException e) {
System.out.println("User already exists!");
}
如果您没有使用spring catch SQLIntegrityConstraintViolationException
try {
ps.executeUpdate("INSERT INTO User....");
} catch (SQLIntegrityConstraintViolationException e) {
// Duplicate user
} catch (SQLException e) {
// Other SQL Exception
}
答案 2 :(得分:-1)
尝试以下一种或多种组合:
从发送电子邮件=的用户中选择1?或者姓名=? //返回&#34; *&#34;不是最佳的,应该避免;只返回您将使用的列。
从发送电子邮件=的用户中选择计数(*)或者姓名=? //喜欢#1,但会返回一个计数。
从用户中选择count(*),其中email + name = the_email + the_name //引入连接操作代替OR但将条件简化为单个表达式。
如果您不介意额外的列,请将连接的电子邮件+名称保存在自己的列中,并查询该列以测试其唯一性。
添加唯一约束仅适用于您希望延迟唯一性检查,直到您准备好保存为止。如果您想要提前检查唯一性,则必须发出查询。