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

使用MySQL唯一索引防止重复,而不是重复搜索?,mysql,node.js,indexing,node-mysql,Mysql,Node.js,Indexing,Node Mysql,我有一个大表(500万行),其中有一个名为“unique_id”的唯一标识符列 我正在通过Node.js(Node-mysqlbindings)运行INSERT查询,有可能会尝试插入重复项 这两种解决方案是: 1) 在插入之前,将“unique_id”作为索引,并检查整个数据库是否存在重复记录: 'SELECT unique_id WHERE example = "'+unique_id+'" LIMIT 1' 2) 将“unique_id”设置为MySQL中的唯一索引,并在不检查重复项的情况

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

我正在通过Node.js(
Node-mysql
bindings)运行INSERT查询,有可能会尝试插入重复项

这两种解决方案是:

1) 在插入之前,将“unique_id”作为索引,并检查整个数据库是否存在重复记录:

'SELECT unique_id WHERE example = "'+unique_id+'" LIMIT 1'
2) 将“unique_id”设置为MySQL中的唯一索引,并在不检查重复项的情况下执行插入。显然,任何重复项都会导致错误,并且不会插入到表中

我的直觉是,解决方案2)更好,因为它可以防止搜索更坏的情况(500万-1)行以查找重复


使用解决方案2有什么缺点吗?

为unique_id列定义唯一的主索引有很多优点:

  • 语义正确性-当前名称不能反映实际情况,因为在名为“unique_id”的列中可能有重复的名称
  • 自动生成唯一ID-您可以将此作业委托给数据库并避免ID冲突(如果您使用UUID而不是整数,这不会是一个问题)
  • 速度增益-要成为可靠的解决方案1,需要阻塞事务(在检查重复和插入行之间不应插入新行)。将此任务委托给MySQL将更有效率
  • 遵循一个共同的模式——这正是唯一索引和主索引设计的目的。您的解决方案将易于其他开发人员理解
  • 更少的代码
在第二种解决方案中,您可能需要处理插入副本的尝试(除非您的唯一ID由MySQL生成)

自动递增的主索引:

令人惊讶的是,它在性能方面几乎没有什么不同。搜索将使用(并且需要)相同的索引

然而,性能差异很小的地方是对您的(2)解决方案的好处

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

INSERT IGNORE INTO ... VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)...;
将始终成功(将跳过插入重复项)。这允许在一条语句中插入多个值,如上所述

您可能还对重复密钥更新上的
技巧系列感兴趣:-)

正如M.M.已经指出的那样,真正的区别在于完整性。使用唯一的索引约束,您可以确定您的数据;否则,您需要在检查表和插入新元组之间锁定表,以避免其他人插入相同值的风险


如果数据的“重复性”需要大量的业务逻辑工作,而这些工作很难转化为MySQL约束,那么您的(1)解决方案可能会有一席之地。那样的话,你会的

  • 锁上桌子
  • 搜索候选副本(假设你得到20份副本)
  • 获取数据并验证它们是否确实是候选对象
  • 如果没有冲突,请插入新元组
  • 松开锁
(有人可能会有充分的理由认为,需要进行如此复杂的旋转木马是因为数据库设计中存在一些错误。理想情况下,您应该能够在MySQL中完成所有工作。但业务现实有时离理想还很远)