0

假设我们有一个 MySQL 后端,其表的主键使用 UNIQUE 属性定义。我们正在接收来自多个分布式系统的数据,这些系统都具有相同/相似的实现。

在某些时候,我们将尝试批量插入例如 1000 万个文档行,但我们只想在不违反唯一约束的情况下存储数据,哪种方法会更快/被认为可以..

例如

try {
    //...try and insert the document
} catch(MySQLIntegrityConstraintViolationException e) {
    //..do nothing, since this is already stored in the database
    //move on to the next one..
}

或者

//we try to find the document...
if(!documentFound) {
    //we did not find a document with this id, so we can safely insert it..
    //move on to the next one...
}

在我的脑海中,我猜测在这两种情况下,我们尝试插入的 id 都必须“找到”,因为我们必须验证唯一约束,但是就其速度而言,两者中的哪一个被认为或多或少是可以的?

附带问题:对于 mongoDB,例如 Mysql 的答案/结果(例如速度)是否相同?

4

3 回答 3

2

你能不能只使用INSERT .. ON DUPLICATE。这样您就不必担心它们的密钥是否已经存在?所以在你的情况下你可以做

ON DUPLICATE KEY UPDATE id=id
于 2013-09-09T14:07:59.377 回答
2

一般来说,我会为...保留例外情况:) 换句话说,如果在正常的工作流程中可能发生某些事情,我宁愿使用常规的if. 空catch子句通常表明有问题。

另外,我宁愿使用该INSERT IGNORE构造(而不是ON DUPLICATE-- 它工作得很好,但我不喜欢 hackish UPDATE id=id)。

如果使用 IGNORE 关键字,则执行 INSERT 语句时发生的错误将被忽略。(...) 忽略的错误可能会生成警告,尽管重复键错误不会。

于 2013-09-09T17:07:10.793 回答
1

如果您坚持遍历记录并逐个处理它们,我会建议另一种方法

伪代码

  1. 创建一个哈希列表
  2. 在哈希列表中搜索唯一键
  3. 如果没有找到就插入数据库。将唯一键添加到哈希列表
  4. 获取下一条记录
  5. 如果不是 eof,则转到 2。

如果您有许多重复项,您将为自己节省大量(相对)昂贵的数据库调用。

于 2013-09-09T14:57:27.160 回答