2014-02-05 64 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