2012-02-08 37 views
17

Tôi có một bảng cơ bản với các cột:gia số tự động Quá nhiều với ON DUPLICATE CẬP NHẬT KEY

  • id (tiểu học với AI)
  • tên (unique)
  • vv

Nếu cột duy nhất không tồn tại, INSERT hàng, nếu không CẬP NHẬT hàng ...

INSERT INTO pages (name, etc) 
VALUES 
    'bob', 
    'randomness' 
ON DUPLICATE KEY UPDATE 
name = VALUES(name), 
etc = VALUES(etc) 

Vấn đề là nếu nó thực hiện một UPDATE, giá trị auto_increment trên cột id tăng lên. Vì vậy, nếu một loạt các CẬP NHẬT được thực hiện, id auto_increment đi qua mái nhà.

Rõ ràng đó là một lỗi: http://bugs.mysql.com/bug.php?id=28781

... nhưng tôi đang sử dụng InnoDB trên mySQL 5.5.8 trên chia sẻ lưu trữ.

Những người khác gặp vấn đề với không có giải pháp năm trước: prevent autoincrement on MYSQL duplicate insertWhy does MySQL autoincrement increase on failed inserts?

Ý tưởng về một sửa chữa? Tôi có thể cấu trúc cơ sở dữ liệu không chính xác bằng cách nào đó không?

****** CHỈNH SỬA ****: Có vẻ như thêm innodb_autoinc_lock_mode = 0 vào tệp my.ini của bạn sẽ khắc phục sự cố nhưng tôi có các tùy chọn nào để chia sẻ lưu trữ?

****** CHỈNH SỬA 2 ******: OK, tôi nghĩ tùy chọn duy nhất của tôi là thay đổi thành MyISAM làm công cụ lưu trữ. Là một người mới mySQL lớn, tôi hy vọng điều đó không gây ra nhiều vấn đề. Ừ?

+0

Một vấn đề lớn với MyISAM là nó không hỗ trợ các định nghĩa của các mối quan hệ cơ sở dữ liệu. InnoDB không hỗ trợ điều đó. – bakkerjoeri

+2

innodb_autoinc_lock_mode = 0 làm việc cho tôi. cảm ơn –

+0

Tôi chuyển sang Aria (MyISAM trong MariaDB) để ngăn chặn auto_increment – DanFromGermany

Trả lời

12

Tôi không nghĩ rằng có cách để bỏ qua hành vi này của INSERT ... ON DUPLICTE KEY UPDATE.

Bạn tuy nhiên có thể đặt hai câu lệnh, một UPDATE và một INSERT, trong một transaction:

START TRANSACTION ; 

UPDATE pages 
SET etc = 'randomness' 
WHERE name = 'bob' ; 

INSERT INTO pages (name, etc) 
SELECT 
     'bob' AS name 
    , 'randomness' AS etc 
FROM dual 
WHERE NOT EXISTS 
     (SELECT * 
     FROM pages p 
     WHERE p.name = 'bob' 
    ) ; 

COMMIT ; 
+0

Cảm ơn anh chàng. Tôi đã đi tuyến đường này. Đó là vấn đề tăng tự động là một nỗi đau trong ass. Không cần các phần "AS name" và "AS etc". –

+0

Không, những bí danh đó là không cần thiết. –

+0

@NathanWaters: Đã thêm liên kết tới tài liệu về giao dịch của MySQL. –

-3

Chức năng chính trên bản sao của MySQL giống hệt như thực hiện hai truy vấn riêng biệt, một để chọn, sau đó một để cập nhật bản ghi đã chọn hoặc chèn bản ghi mới. Làm như vậy lập trình chỉ là nhanh và sẽ ngăn chặn vấn đề này trong tương lai cũng như làm cho mã của bạn dễ dàng hơn.

+3

nó không phải là gần như nhanh chóng theo những gì tôi nhìn thấy –

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