如何检查多个表中是否存在给定数据(所有表都有相同的列)?

Ted*_*Ted 12 mysql sql

我有3个表,每个表都包含一个名为username的列.在注册部分,我需要检查所请求的用户名是否是新的和唯一的.

在我继续之前,我需要一个单独的SQL来告诉我这些用户是否存在于这些表中.我试过了:

SELECT tbl1.username, tbl2.username, tbl3.username
FROM tbl1,tbl2,tbl3
WHERE tbl1.username = {$username}
   OR tbl2.username = {$username}
   OR tbl3.username ={$username}
Run Code Online (Sandbox Code Playgroud)

这是要走的路吗?

Red*_*ter 23

select 1 
from (
    select username as username from tbl1
    union all
    select username from tbl2
    union all
    select username from tbl3
) a
where username = 'someuser'
Run Code Online (Sandbox Code Playgroud)

  • 尼斯'给男人一个鱼回答',但这并不能解决潜在的问题. (3认同)

Mic*_*ays 15

如果你真的只是想知道用户是否存在:

最快的方法是存在查询:

select 
NOT EXISTS (select username from a where username = {$username}) AND 
NOT EXISTS (select username from b where username = {$username}) AND 
NOT EXISTS (select username from c where username = {$username});
Run Code Online (Sandbox Code Playgroud)

如果您的username列被标记为Unique在每个表中,这应该是您能够执行此操作的最有效查询,并且这在内存使用方面优于标准化的用户名表,以及几乎任何其他查询关心username和另一个专栏,因为没有过多的联接.如果您曾被要求加速组织的数据库,我可以向您保证,过度规范化是一场噩梦.关于你在这个帖子中关于规范化的建议,要小心.它非常适合限制空间或限制更新数据所需的位置数量,但您必须权衡维护和速度开销.在这个页面上给你带来一些盐的建议.

习惯于在查询上运行查询分析器,如果没有其他原因,除了习惯于在编写查询时学习选择的后果 - 至少在你得到你的支持之前.

如果您想稍后插入用户:

如果您这样做是为了最终将用户添加到数据库中,这是一种更好的方法,值得学习它.尝试立即插入值.之后检查是否成功.这样,在您检查的时间和插入数据库的时间之间,没有空间进行其他数据库调用以插入记录.例如,在MySQL中你可以这样做:

INSERT INTO {$table} (`username`, ... )
  SELECT {$username} as `username`, ... FROM DUAL 
   WHERE 
     NOT EXISTS (select username from a where username = {$username}) AND 
     NOT EXISTS (select username from b where username = {$username}) AND 
     NOT EXISTS (select username from c where username = {$username});
Run Code Online (Sandbox Code Playgroud)

我见过的所有数据库API,以及所有SQL实现都将为您提供一种方法来发现插入了多少行.如果为1,则用户名不存在且插入成功.在这种情况下,我不知道你的方言,所以我选择了MySQL,它提供了一个DUAL专门用于返回未绑定到表的结果的表,但老实说,有很多方法可以使这只猫变亮,无论是您将它放在事务或存储过程中,或严格限制可以访问这些表的过程和过程.

更新 - 如何处理未完成注册过程的用户

正如@RedFilter指出的那样,如果注册是通过多个步骤完成的 - 保留用户名,填写详细信息,或者回复确认电子邮件,那么您至少需要添加一列来标记此用户(带有时间戳,而不是boolean)以便您可以在一段时间后定期删除用户,但我建议创建一个ToBePurged表并添加新用户以及时间戳.确认到来后,您将从此表中删除该用户.您会定期检查此表中是否存在当前时间某些增量之前的所有条目,只需将它们从最初添加的表中删除即可.我背后的理念是更清楚地定义表格的责任,并保持您工作的记录数量非常精简.我们当然不希望过度设计我们的解决方案,但如果您养成良好的架构实践习惯,这些设计将会像效率较低的同行一样自然流出.