2012-12-01 49 views
3

我正在使用PHP/MySQL。检查用户名是否已被使用的最佳方法是什么?如何正确检查用户名是否被采用?

现在我所做的只是执行select语句来查看用户名是否已被占用。如果select返回一行然后我停止并显示一条错误消息。如果select没有返回任何内容,那么我插入新的用户。

但是有没有更高效的方法?例如,我可以在用户名列上使用UNIQUE,然后只执行一条插入语句(如果插入语句已被占用,则会从插入语句中获取错误)。

+0

Ofourse您可以在用户名列上使用UNIQUE,否则给予某人一个UNIQUE用户名有什么意义......;)[请检查此问题](http://stackoverflow.com/questions/) 12829405/insert-statement) – bonCodigo

回答

5

您确实有一些其他线程会在您的SELECT确认该用户不存在与您插入它的INSERT之间的短暂时刻插入您的用户名。这被称为race condition

它可能看起来像这种事情发生的几率是很小的,但是有一个说法有关:“One in a million is next Tuesday.

是,在用户名UNIQUE约束可以防止你插入一个重复的用户名。声明那个约束。

有些文章会告诉你,一旦你有一个UNIQUE约束,你就不必再做SELECT了。只需尝试 INSERT,如果它冲突,则报告错误。

但是,我帮助一个网站从这个技术引起的问题恢复。在他们的网站上,用户试图很快创建新的用户名,并导致INSERT上的很多冲突。问题是,MySQL increments the auto-increment primary key for the table, even if the INSERT was canceled。而这些自动增量值永远不会被重用。所以结果是他们每个成功的INSERT失去了1000-1500个ID号码。当他们的INT主键达到2 -1时,他们打电话给我,他们无法在表中创建另一行!

他们使用的解决方案是首先尝试SELECT,并报告重复。然后,如果看起来很安全,请尝试INSERT - 但编写代码以处理与UNIQUE约束可能的冲突,因为竞争条件仍然可能发生。

+0

为什么他们不能仅仅事务处理select和insert? – FoolishSeth

+0

伟大的观点和轶事! – inhan

+1

@FoolishSeth,SELECT不锁定任何东西,所以它不会阻塞任何并发的INSERT。如果您开始交易,这没有帮助。 –

相关问题