2012-11-22 48 views
16

tôi phải cập nhật một bảng với cấu trúc sau:MySQL 5.5.24 - nhập trùng lặp trên UPDATE, khi không có trùng lặp thực

CREATE TABLE `eav_entity_attribute` (
    `entity_attribute_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Entity Attribute Id', 
    `entity_type_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type Id', 
    `attribute_set_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Set Id', 
    `attribute_group_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Group Id', 
    `attribute_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Id', 
    `sort_order` smallint(6) NOT NULL DEFAULT '0' COMMENT 'Sort Order', 
    PRIMARY KEY (`entity_attribute_id`), 
    UNIQUE KEY `UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_ATTRIBUTE_ID` (`attribute_set_id`,`attribute_id`), 
    UNIQUE KEY `UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID` (`attribute_group_id`,`attribute_id`), 
    KEY `IDX_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_SORT_ORDER` (`attribute_set_id`,`sort_order`), 
    KEY `IDX_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID` (`attribute_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Eav Entity Attributes' 

Trên bảng chứa một hàng duy nhất:

INSERT INTO `eav_entity_attribute` 
(`entity_attribute_id`, `entity_type_id`, `attribute_set_id`, `attribute_group_id`, `attribute_id`, `sort_order`) 
VALUES 
(32758, 4, 224, 3423, 5171, 12) 

Tôi đang chạy một thủ tục nhập tự động, sẽ đọc một nguồn dữ liệu bên ngoài và viết vào bảng này.

Quá trình nhập này chạy nhiều lần và do đó, đôi khi cùng một dữ liệu được nhập nhiều lần. Trong trường hợp này, thủ tục chỉ ghi đè lên dữ liệu cũ với dữ liệu mới, ngay cả khi quy trình mới giống với cũ. Điều kiện tồn tại cùng một dữ liệu được xử lý với mệnh đề ON DUPLICATE KEY UPDATE. Điều này hoạt động gần như hoàn hảo, ngoại trừ trên bảng cụ thể này.

Trên bảng này, khi thủ tục thử UPDATE, tôi nhận được thông báo "Khóa trùng lặp", mà tôi không thể giải thích. Tôi sửa lỗi mã, và điều này là truy vấn thất bại (chiết xuất từ ​​INSERT..ON DUPLICATE KEY):

UPDATE eav_entity_attribute 
SET 
    `attribute_group_id` = 3423 
    ,`attribute_id` = 5171 
    ,`attribute_set_id` = 223 
    ,`entity_type_id` = 4 
    ,`sort_order` = 320 
WHERE 
    (`attribute_group_id` = 3423) AND 
    (`attribute_id` = 5171) 

Các lỗi như sau:

Error Code: 1062. Duplicate entry '3423-5171' for key 'UNQ_EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID' 

Tôi biết rằng các cặp 3423 -5171 đã tồn tại, nhưng UPDATE sẽ tự thay thế các giá trị này, chứ không phải tạo một mục mới. Tôi khá bối rối về nguyên nhân của vấn đề này, bất kỳ đề nghị nào cũng sẽ rất được hoan nghênh. Cảm ơn.

Update - New tìm

Tôi có một số loại "nguồn cảm hứng" và tôi đã thực hiện một thử nghiệm. Tôi đã xóa ràng buộc Duy nhất liên quan đến số (attribute_set_id, attribute_id) (lưu ý, đây không phải là lỗi trong lỗi) và tôi đã chạy truy vấn INSERT..ON DUPLICATE. Nó hoạt động hoàn hảo.

Mine là một phỏng đoán, nhưng đây là những gì tôi nghĩ: dữ liệu tôi đang cố gắng để viết thư cho các vụ đụng độ bảng với hai khó khăn:

  • UNIQUE (attribute_set_id, attribute_id)
  • UNIQUE (attribute_group_id , attribute_id)

các INSERT thất bại, có lẽ vì các lỗi trùng lặp nuôi dưỡng bởi các chế đầu tiên. Điều này kích hoạt UPDATE, sử dụng ràng buộc đầu tiên như mệnh đề WHERE ngầm định. Suy đoán của tôi là, trong trường hợp như vậy, ràng buộc đầu tiên là bằng cách nào đó bỏ qua, nhưng các chuyến đi UPDATE trên thứ hai, mà đã không được tham gia trước đó.

Điều này vẫn không có vẻ đối với tôi, một lý do hợp lệ cho một CẬP NHẬT thay thế một cái gì đó với chính nó để tăng lỗi trùng lặp, nhưng nó có thể làm sáng tỏ một chút về logic đằng sau nó.

Second Cập nhật

tôi phát hiện ra rằng các bảng tôi đã được thử nghiệm chống lại thực sự chứa rất nhiều hàng (tôi quên tắt chế độ xem lọc) phát sinh từ việc nhập khẩu thành công các dữ liệu khác.Tuy nhiên, "ứng viên trùng lặp" vẫn là duy nhất trong tập hợp.

Tôi xác nhận nội dung được đăng trong nhận xét, khi bảng chỉ chứa các hàng đó, INSERT..ON DUPLICATE hoạt động, cũng như chỉ UPDATE. Bây giờ tôi tự hỏi tại sao bảng bị rối tung lên khi có nhiều dữ liệu hơn trong đó, vì chúng ta vẫn đang nói về một hàng duy nhất đang được cập nhật với cùng một dữ liệu.

thứ ba Cập nhật - Tìm thấy nguyên nhân gốc rễ

cuối cùng tôi phát hiện ra lý do tại sao CẬP NHẬT thất bại, bây giờ tôi phải tìm hiểu làm thế nào để tôi nhận được trong tình trạng như vậy.

Đầu mối là phỏng đoán của tôi trong lần cập nhật đầu tiên. Đơn giản, tôi có hai hàng rất giống nhau (xin lưu ý rằng tôi đang sử dụng các giá trị khác nhau khi tôi bắt đầu từ một cơ sở dữ liệu sạch).

row,entity_attribute_id,entity_type_id,attribute_set_id,attribute_group_id,attribute_id,sort_order 
1,16919, 4, 120, 1746, 80, 1 
2,16649, 4, 119, 1744, 80, 210 

Đây là những gì sẽ xảy ra:

  • Các INSERT cố gắng để chèn một hàng với các giá trị sau: 120, 4, 1744, 80, 54.
  • Điều này kích hoạt "khóa trùng lặp", vì các giá trị 120, 80 trùng lặp với các trường attribute_set_id, attribute_id (hàng 1).
  • MySQL sau đó cố gắng UPDATE, mà trở thành như sau:

    UPDATE bảng entity_type_id = 4 , attribute_group_id = 1744 , sort_order = 54 ĐÂU (attribute_set_id = 120) AND (attribute_id = 80)

  • Lần này, UPDATE không thành công do các giá trị 1744,80 vi phạm ràng buộc đối với cặp attribute_group_id, attribute_id, được tìm thấy trong hàng 2.

Nói tóm lại

  • Các INSERT không thành công vì dòng 1 có giá trị giống cho phím attribute_set_id, attribute_id.
  • CẬP NHẬT CẬP NHẬT vì hàng 2 có cùng giá trị cho khóa attribute_group_id, attribute_id.

Giải pháp

tôi sẽ phải xem xét các thủ tục nhập khẩu toàn bộ, như, về mặt lý thuyết, không ai trong số các bản sao như vậy nên nảy sinh. MySQL đang làm tốt công việc của mình, đó là cơ sở dữ liệu phức tạp.

Cảm ơn tất cả các đề xuất.

+0

MySQL 5.5.24. Tôi đã thêm nó vào tiêu đề. – Diego

+3

Lạ, hoạt động ở 5.5.28. http://sqlfiddle.com/#!2/81569 –

+1

Nó hoạt động trong 5.5.20 với các truy vấn từ câu hỏi; đó là kích thước của bảng quan trọng ở đây, tôi giả sử. – raina77ow

Trả lời

2

Cố gắng không cập nhật các giá trị khóa trong mệnh đề UPDATE của INSERT ... ON DUPLICATE KEY UPDATE. Thật kỳ lạ khi yêu cầu MySQL thay đổi các giá trị khóa nếu một bản ghi với các giá trị khóa này đã tồn tại, do đó, hành vi bất ngờ của MySQL không đáng ngạc nhiên.

+0

Sử dụng 'ON DUPLICATE KEY UPDATE' không dẫn đến bất kỳ hành vi lạ nào, vấn đề là do một loạt các trường hợp và hiện đã được giải quyết. Tôi đang chuẩn bị một câu trả lời hoàn chỉnh. – Diego

+0

Âm thanh như câu trả lời này khá gần! Bản cập nhật cho giá trị khóa bên trong trên bản cập nhật khóa trùng lặp chắc chắn là thủ phạm. (Chỉ báo trước tôi đoán là MySQL cư xử theo cách mong đợi ngay cả trong những trường hợp này) –

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