2014-02-05 65 views
8

我做多个插入在查询:mysql是否在单个查询原子中插入多个?

INSERT INTO table (c1, c2) VALUES (1,2), 
            (2,3), 
            (3,4),...... 
     ON DUPLICATE KEY UPDATE c2 = VALUES(c2) 

现在假设有超过数万查询(因此省略号)指定的价值....

灿在某些情况下,VALUES的某些部分设法在数据库中插入/更新,但其余部分由于某些数据库错误/失败/内存​​耗尽等原因而未能插入/更新?

mysql是否查询ALL或Nothing?

这是真的,每一个MySQL查询执行的,无论是在查询中指定的所有值将被插入/更新顺利,或没有价值的将被插入/更新?

+1

在任何符合ACID的数据库中,对“插入”的单个调用应该是原子的。 –

+0

为什么你不测试它 - 你不需要数百个数据点来测试它! – gvee

+0

可能重复[是连接插入/更新MySQL的原子操作?](http://stackoverflow.com/questions/19444623/is-join-insert-update-on-mysql-an-atomic-operation) – Daniel

回答

11

ACID(Atomicity,Consistency,Isolation,Durability)属性用于描述数据库中的这种行为。原子性只有在处理concurrent modifications时才重要。为确保一致性,必须达到一定的隔离级别。然而,越孤立的多个事务运行,DBMS通常具有的性能越低。所以有所谓的“isolation level”,它指出了DBMS中可能发生哪些错误,哪些不能。现在

,MySQL的实现InnoDB的数据库中的所有隔离级别,你可以选择每笔交易:https://dev.mysql.com/doc/refman/5.1/en/set-transaction.html

的MyISAM数据库不支持事务,单操作应但是原子运行。 (来源:https://dev.mysql.com/doc/refman/5.0/en/ansi-diff-transactions.html)。但是请注意,这并不保证数据在一次操作中的读写操作之间不会发生变化 - DBMS中的原子性仅表示操作完全完成或完全跳过。它不保证隔离性,一致性或耐用性。

+1

我可以问一下downvote是干什么的?我没有看到任何意见或编辑建议... –

+1

。 。 。那里有恶意下流者。我认为这是一个很好的答案。 +1。 –

+2

@JohannesH。这可能是因为MySQL链接指向德国文档=)修正了它。 –

1

它的表存储引擎是InnoDB,是的,该操作是绝对原子的,并且部分插入是不可能的。我相信MyISAM是默认引擎,因为它不符合ACID标准并且不支持事务。

+0

MyISAM是原子的,但不一定一致,持久或孤立。看到我的答案。 –

+0

MyISAM不是**原子的,因为该术语通常适用于数据库系统。 –

+0

@MarcusAdams看到你的观点。同意,这应该是“MyISAM数据库实施'原子操作'作为完整性方案”。它更像是在DBMS术语之外使用的“原子”方式。 –

0

这样的单个语句是。如果您需要以原子方式执行多个呼叫,则可以在大多数关系数据库中使用transactions

+0

由于这是MySQL的具体意思,所以必须使用INNODB表,因为MyIsam不支持事务。 –

+0

我想说,如果你问这个问题,你应该使用InnoDB。如果数据完整性至关重要,那么InnoDB几乎总是更好。 – krowe

+0

完全和你在一起,虽然OP艾米不知道。此外,由于我们正在讨论大量的数据(根据OP),速度可能是一个问题,尽管MyISAM有一点意义。 –

4

“可曾有过在其值的一些地方设法得到插入的情况下/由于某种DB错误的更新数据库,但其余没有得到插入/更新可能/失败/内存​​ - 跑出去了吗?“

晚的答案,但也许是有趣:[ON DUPLICATE KEY] UPDATE严格原子的单排(既不MyISAM,也不InnoDB),但它会在问候的错误是原子的。

有什么区别?好吧,这说明在承担严格的原子潜在的问题:

CREATE TABLE `updateTest` (
    `bar` INT(11) NOT NULL, 
    `foo` INT(11) NOT NULL, 
    `baz` INT(11) NOT NULL, 
    `boom` INT(11) NOT NULL, 
    PRIMARY KEY (`bar`) 
) 
COMMENT='Testing' 
ENGINE=MyISAM; 

INSERT INTO `updateTest` (`bar`, `foo`, `baz`, `boom`) VALUES (47, 1, 450, 2); 

INSERT 
    `updateTest` 
    (`bar`, `foo`, `baz`, `boom`) 
VALUES 
    (47, 0, 400, 5) 
ON DUPLICATE KEY UPDATE 
    `foo` = IF(`foo` = 1, VALUES(`foo`), `foo`), 
    `baz` = IF(`foo` = 1, VALUES(`baz`), `baz`), 
    `boom` = IF(`foo` = 1, VALUES(`boom`), `boom`); 

(47, 1, 450, 2)会已经变成了(47, 0, 450, 2),而不是为(47, 0, 400, 5)。如果你假设严格原子性(这不是说你应该;你可能更喜欢这种行为),那应该不会发生 - foo应该不会发生改变之前其他列的值甚至评估foo应与其他列一起更改 - 全部或全部不变

如果我说原子的问候错误,我的意思是,如果你删除多数民众赞成突出严格的情况下,这样上面的例子中IF()条件...

INSERT INTO `updateTest` (`bar`, `foo`, `baz`, `boom`) VALUES (48, 1, 450, 2); 

INSERT 
    `updateTest` 
    (`bar`, `foo`, `baz`, `boom`) 
VALUES 
    (48, 0, 400, 5) 
ON DUPLICATE KEY UPDATE 
    `foo` = VALUES(`foo`), 
    `baz` = VALUES(`baz`), 
    `boom` = VALUES(`boom`); 

...你永远要么(48, 1, 450, 2)(48, 0, 400, 5)您的发言结束后/坠毁,并一些中间状态一样(48, 0, 450, 2)结束。

对于UPDATE的行为也是如此,但因为您可以将条件语句放入您的WHERE子句中,所以更有理由在此处处理IF()语句。

结论:在边缘情况之外,即使使用MyISAM,您也确实对单行语句具有原子性。见Johannes H.'s answer for further information