通过尝试插入来测试MYSQL中的重复记录

通过尝试插入来测试MYSQL中的重复记录

问题描述:

我在写一个将用户插入MYSQL表的函数。最初我写了这样一个功能,它首先会用SELECT声明检查具有相同用户名的现有用户。但是,我的表指定用户名列是唯一的,所以我意识到在检查用户是否存在后,数据库会再次检查。通过尝试插入来测试MYSQL中的重复记录

只是尝试插入该行并查看是否有错误或者是否明确地检查了SELECT语句会更好吗?

不知道很多关于你的环境,编程语言,负载,性能等我要说坚持什么让你感觉良好!

这两种情况都没有错;)

想想并编写常见的场景。我的意思是,你是说这是为新的注册用户。那么,你认为用户会多频繁地尝试重新注册?对!我会在这种情况下尝试插入第一种情况。

您是否认为您的插入失败率很高,那么首先进行选择检查是很好的。

+0

如果我预期失败率很高,难道我不想避免额外支票来摆脱开销吗? – bytesized

+1

在这种情况下(比db引擎中的错误处理成本更高),对高速插入失败进行选择检查的代价将更容易。所有都可以测量,你可以设置一个负载并运行这两种方案来查看你的数据库引擎行为。如上所述,如果您正在寻找性能增益的常见场景代码 – MrSimpleMind

+0

有趣。我没有意识到在数据库引擎中的错误处理会有很大的开销(我猜这是有道理的)。但是,最终,我打算所有的验证都通过客户端完成(在这种情况下通过AJAX)。因此,我预计失败率很低,所以我认为我会先插入,然后再提问。 – bytesized

如果这是基于Web的应用程序,我会通过Ajax请求执行检查以获得更好的最终用户体验。

+0

我打算这样做,但问题是关于在后端创建用户功能 – bytesized

+0

如果您已验证您的dB,用户名不存在允许用户提交表单。否则,请不要提交表单,以便每个用户名只提供一次dB检查。我不认为有必要采取另一项安全措施。 –

您正在寻找INSERT IGNORE。在重复主键插入时,它将生成警告而不是错误,并且您不需要运行SELECT来检查重复项。

https://dev.mysql.com/doc/refman/5.5/en/insert.html

+0

阅读了一下你链接到的文档后,这听起来就像我想要的相反。这不妨碍我想用来检测重复的用户名的确切错误吗?看起来这样会导致服务器显示“全部完成,您的用户名现在存在”,实际上什么都没有完成。 – bytesized

这取决于你如何做检查。

当你在insert之前做select时,你有一个竞争条件。另一个用户/线程可以在,selectinsert之间插入重复记录。这就是为什么你想要在insert做检查。

通常,在insert中进行检查就足够了。如果您想避免该错误,请使用on duplicate key update。这比insert ignore更可取,因为on duplicate key update只能处理有关密钥重复的错误。 Insert ignore忽略所有错误。

我会说,除非你有某些特殊的原因,否则不要打扰手边的检查。原因如下:

  • 想要最小化表被锁定的时间,因此您希望避免提出问题,例如“发生重复时表锁定多长时间?”。
  • auto_increment列中的故意漏洞会打扰您(实际上,我不确定这是MySQL的问题)。
  • 您插入多行,并希望能够检测多个重复报告给用户。