2012-08-30 36 views
15

Chức năng REPLACE INTO trong MySQL hoạt động theo cách xóa và chèn hàng. Trong bảng của tôi, khóa chính (id) được tự động tăng lên, vì vậy tôi đã mong đợi nó xóa và sau đó chèn một bảng với id ở đuôi của cơ sở dữ liệu.REPLACE INTO, nó có sử dụng lại PRIMARY KEY không?

Tuy nhiên, nó không mong muốn và chèn nó với cùng một id! Đây có phải là hành vi mong đợi hay tôi đang thiếu thứ gì đó ở đây? (Tôi không đặt số id khi gọi số REPLACE INTO)

+5

Không thể tái tạo: 'TẠO BẢNG TABLE (id INT PRIMARY KEY AUTO_INCREMENT, tên VARCHAR (20) NOT NULL UNIQUE, giá trị VARCHAR (200) NOT NULL); REPLACE INTO kiểm tra (tên, giá trị) GIÁ TRỊ ('foo', 'bar'); REPLACE INTO kiểm tra (tên, giá trị) GIÁ TRỊ ('foo', 'baz'); SELECT id FROM test, 'trả về 2, không 1 - dường như' id' đã được tăng lên hai lần. (chỉnh sửa: thử nghiệm với cả InnoDB và MyISAM) – lanzz

+0

Bạn đang sử dụng công cụ lưu trữ nào trên bảng này? –

+0

Hành vi bạn đang quan sát không nhất quán với hành vi mong đợi. Một giải thích có thể là thao tác DELETE không thành công, có thể do vi phạm ràng buộc khoá ngoại. Đó là điều duy nhất tôi có thể nghĩ đến. Không thể làm nhiều hơn nữa để giúp đỡ mà không có một trường hợp thử nghiệm đáng kể hơn mà chứng minh các hành vi quan sát. – spencer7593

Trả lời

14

Đây là hành vi được mong đợi nếu bạn có một chỉ mục khác là UNIQUE trong bảng mà bạn phải có nếu không nó sẽ thêm hàng như bạn mong đợi. Xem tài liệu:

THAY THẾ hoạt động chính xác như INSERT, ngoại trừ nếu hàng cũ trong bảng có cùng giá trị như hàng mới cho khóa CHÍNH hoặc chỉ số UNIQUE, hàng cũ bị xóa trước mới hàng được chèn vào. Xem Phần 13.2.5, “Cú pháp INSERT”.

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

Điều này thực sự cũng làm cho rất nhiều ý nghĩa bởi vì làm thế nào khác mySQL sẽ tìm hàng để thay thế? Nó chỉ có thể quét toàn bộ bảng và điều đó sẽ tốn thời gian. Tôi đã tạo ra một Fiddle SQL để chứng minh điều này, xin vui lòng có một cái nhìn here

+2

OP xác định rằng anh ta không cung cấp giá trị cho cột 'id'. Nếu câu lệnh đã cung cấp một giá trị cho cột 'id', thì có, chúng tôi mong đợi giá trị sẽ được" sử dụng lại ". Nhưng nếu không có giá trị nào được cung cấp, chúng tôi mong đợi hành vi AUTO_INCREMENT bình thường. – spencer7593

+0

Hãy để tôi chỉnh sửa câu trả lời của mình – hol

+1

Thật vậy, tôi có một chỉ mục 'UNIQUE' khác như bạn đã mô tả. Cảm ơn rất nhiều vì sự giúp đỡ. :) – matt

3

Đó là hành vi mong đợi. Về mặt kỹ thuật, trong trường hợp TẤT CẢ các khóa duy nhất (không chỉ là khóa chính) trên dữ liệu được thay thế/chèn vào là khớp với hàng hiện có, MySQL thực sự xóa hàng hiện tại của bạn và chèn một hàng mới với dữ liệu thay thế. cho tất cả các phím duy nhất. Vì vậy, nếu bạn nhìn để xem số hàng bị ảnh hưởng trên truy vấn như vậy, bạn sẽ nhận được 2 hàng bị ảnh hưởng cho mỗi thay thế và chỉ một cho các chèn thẳng.

+1

Điều đó không thực sự giải thích tại sao một ID sẽ được sử dụng lại. –

+0

Trên thực tế, người hỏi (đúng) dự kiến ​​tự động của mình 'id' được phân bổ một lần nữa với sự thay thế, nhưng anh ta quan sát một' id' được bảo tồn. – lanzz

+1

Bạn có một trường hợp thử nghiệm thể hiện hành vi này không? Lời giải thích của bạn về hành vi này trái ngược với hành vi mà tôi đã trải qua, với cả MyISAM và InnoDB. – spencer7593

Các vấn đề liên quan