使用MySQL唯一索引来防止重复,而不是重复搜索?

时间:2017-01-09 13:31:26

标签: mysql node.js indexing node-mysql

我有一个大表(500万行),有一个名为'unique_id'的唯一标识符列

我正在通过Node.js(node-mysql绑定)运行INSERT查询,并且可能会尝试插入重复项。

这两个解决方案是:

1)将'unique_id'作为索引,并在INSERT之前检查整个数据库是否有重复记录:

'SELECT unique_id WHERE example = "'+unique_id+'" LIMIT 1'

2)使'unique_id'成为MySQL中的唯一索引,并执行INSERT 而不用检查重复项。显然,任何重复都会导致错误而不会被插入表中。

我的预感是解决方案2)更好,因为它可以防止搜索更糟糕的(500万 - 1)行的副本。

使用解决方案2是否有任何缺点?)

2 个答案:

答案 0 :(得分:2)

为unique_id列定义唯一的主索引有很多好处:

  • 语义正确性 - 目前名称并不反映现实,因为您可以在名为' unique_id',
  • 的列中包含重复项
  • 自动生成唯一ID - 您可以将此作业委托给数据库并避免ID冲突(如果您使用的是UUID而不是整数,这不会有问题),
  • 速度增益 - 成为可靠的解决方案1需要阻塞事务(在检查重复和插入行之间不应插入新行)。将此委托给MySQL会更有效率,
  • 遵循一个共同模式 - 这正是设计要做的唯一和主要索引。您的解决方案很容易被其他开发人员理解,
  • 少量代码。

使用第二个解决方案,您可能需要处理插入重复的尝试(除非您的唯一ID由MySQL生成)。

自动增量主索引: https://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html

答案 1 :(得分:1)

令人惊讶的是,它在性能方面没什么区别。搜索将使用(并要求)相同的索引。

然而,你的(2)解决方案的优点是什么性能差异很小。

实际上在MySQL中你可以使用IGNORE关键字完全消除错误:

INSERT IGNORE INTO ... VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)...;

将始终成功(将跳过插入重复项)。这允许在单个语句中插入多个值,如上所述。

您可能也对ON DUPLICATE KEY UPDATE系列技巧感兴趣: - )。

真正的区别,如M.M.已经说明,是诚信。使用UNIQUE索引约束,您可以确定您的数据;否则,你需要在检查它和插入新元组的那一刻之间锁定表,以避免其他人插入相同值的风险。

如果数据的“重复性”需要重要的业务逻辑工作,那么您的(1)解决方案可能会占有一席之地,这不能轻易地转换为MySQL约束。在那种情况下你会

  • 锁定桌子,
  • 搜索候选副本(假设你得到20个),
  • 获取数据并验证他们真正的候选人
  • 如果没有冲突则插入新元组,
  • 释放锁。

(可能有充分理由认为,做这么复杂的旋转木马的必要性源于数据库设计中的一些错误。理想情况你应该能够在MySQL中做所有事情但是商业现实有时会远非理想。