2012-08-30 26 views
15

MySQL中的REPLACE INTO函數的工作方式是刪除並插入行。在我的表中,主鍵(id)是自動遞增的,所以我期待它刪除,然後在數據庫的尾部插入一個帶有id的表。REPLACE INTO,它是否重新使用PRIMARY KEY?

然而,它意想不到,並插入它與相同的id!這是預期的行爲,還是我在這裏錯過了一些東西? (我在撥打REPLACE INTO時沒有設置id

+5

不能重現:'CREATE TABLE test(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20)NOT NULL UNIQUE,value VARCHAR(200)NOT NULL); REPLACE INTO test(name,value)VALUES('foo','bar'); REPLACE INTO test(name,value)VALUES('foo','baz'); SELECT id FROM test;'返回2,而不是1 - 顯然'id'已經增加了兩次。 (編輯:用InnoDB和MyISAM測試) – lanzz

+0

你在這張桌子上使用了什麼存儲引擎? –

+0

您正在觀察的行爲與預期的行爲不一致。一種可能的解釋是DELETE操作不成功,可能是由於違反外鍵約束。這是我能想到的唯一的事情。如果沒有更實質的測試用例來證明觀察到的行爲,就無法做更多的事情。 – spencer7593

回答

14

這是一個預期的行爲,如果您的表中有另一個UNIQUE索引,您必須具有其他索引,否則它將按您的預期添加該行。請參閱文檔:

更換作品酷似INSERT,不同之處在於,如果一個老行的表具有相同的值作爲一個主鍵或唯一索引的新行,舊的行之前的新刪除行插入。請參見第13.2.5節「INSERT語法」。

https://dev.mysql.com/doc/refman/5.5/en/replace.html

這確實也讓很多的意義,因爲怎麼回事,會發現MySQL的行來代替?它只能掃描整個桌子,這會很耗時。我創建了一個SQL小提琴來演示這個,請看看here

+2

OP指定他沒有爲「id」列提供值。如果語句爲'id'列提供了一個值,那麼是的,我們期望值被「重用」。但是,如果沒有提供任何值,我們期望AUTO_INCREMENT行爲正常。 – spencer7593

+0

讓我編輯我的答案 – hol

+1

確實,我已經有了另一個'UNIQUE'索引,正如你所描述的那樣。非常感謝您的幫助。 :) – matt

3

這是預期的行爲。從技術上講,如果要替換/插入的數據上的所有唯一鍵(不僅僅是主鍵)與現有行匹配,MySQL實際上會刪除現有行,並使用相同的值插入帶有替換數據的新行爲所有的唯一鍵。因此,如果您查看此類查詢中受影響的行數,則每個替換將得到2個受影響的行,並且對於直接插入只有一個受影響的行。

+1

這並不能解釋爲什麼一個ID會被重用。 –

+0

實際上,提問者(正確)期望他的自動增量'id'在替換時被重新分配,但他觀察到了一個保留的'id'。 – lanzz

+1

你有一個測試案例來證明這種行爲嗎?您的行爲解釋與MyISAM和InnoDB所經歷的行爲相反。 – spencer7593