Ngày 18 tháng 10 năm 2007
Để bắt đầu: kể từ MySQL mới nhất, cú pháp được trình bày trong tiêu đề là không thể. Nhưng có một số cách rất dễ dàng để thực hiện những gì được mong đợi bằng cách sử dụng chức năng hiện có.
Có 3 giải pháp khả thi: sử dụng CHỨNG CHỈ IGNORE, THAY THẾ hoặc CHỨNG MINH TRÊN CẬP NHẬT KHÓA NGHIÊM TRỌNG.
Hãy tưởng tượng chúng ta có một bảng:
CREATE TABLE `transcripts` (
`ensembl_transcript_id` varchar(20) NOT NULL,
`transcript_chrom_start` int(10) unsigned NOT NULL,
`transcript_chrom_end` int(10) unsigned NOT NULL,
PRIMARY KEY (`ensembl_transcript_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Bây giờ hãy tưởng tượng rằng chúng ta có một đường ống tự động nhập dữ liệu siêu dữ liệu từ siêu dữ liệu từ Makeembl và do nhiều lý do khác nhau, đường ống có thể bị phá vỡ ở bất kỳ bước thực hiện nào. Vì vậy, chúng ta cần đảm bảo hai điều:
thực hiện lặp lại các đường ống sẽ không phá hủy cơ sở dữ liệu của chúng tôi
thực thi lặp đi lặp lại sẽ không chết do lỗi 'trùng lặp khóa chính'.
Phương pháp 1: sử dụng REPLACE
Nó rất đơn giản:
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Nếu hồ sơ tồn tại, nó sẽ bị ghi đè; nếu nó chưa tồn tại, nó sẽ được tạo ra. Tuy nhiên, sử dụng phương pháp này không hiệu quả đối với trường hợp của chúng tôi: chúng tôi không cần ghi đè lên các bản ghi hiện có, chỉ cần bỏ qua chúng.
Phương pháp 2: sử dụng INSERT IGNORE Cũng rất đơn giản:
INSERT IGNORE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Ở đây, nếu 'oblembl_transcript_id' đã có trong cơ sở dữ liệu, nó sẽ bị bỏ qua trong âm thầm (bỏ qua). (Nói chính xác hơn, đây là trích dẫn từ tài liệu tham khảo MySQL: Từ Nếu bạn sử dụng từ khóa IGNORE, các lỗi xảy ra trong khi thực hiện câu lệnh INSERT được coi là cảnh báo thay vào đó. Ví dụ, không có IGNORE, một hàng trùng lặp chỉ mục UNIITE hiện có hoặc giá trị PRIMARY KEY trong bảng gây ra lỗi khóa trùng lặp và câu lệnh bị hủy bỏ. nghiêm trọng.) Nếu bản ghi chưa tồn tại, nó sẽ được tạo.
Phương pháp thứ hai này có một số điểm yếu tiềm ẩn, bao gồm cả việc không hủy bỏ truy vấn trong trường hợp có bất kỳ vấn đề nào khác xảy ra (xem hướng dẫn). Do đó, nó nên được sử dụng nếu được kiểm tra trước đó mà không có từ khóa IGNORE.
Phương pháp 3: sử dụng INSERT trên ON CẬP NHẬT KHÓA HỌC:
Tùy chọn thứ ba là sử dụng INSERT … ON DUPLICATE KEY UPDATE
cú pháp và trong phần CẬP NHẬT, không cần thực hiện một số thao tác vô nghĩa (trống), như tính toán 0 + 0 (Geoffray đề nghị thực hiện gán id = id cho công cụ tối ưu hóa MySQL để bỏ qua thao tác này). Ưu điểm của phương pháp này là nó chỉ bỏ qua các sự kiện quan trọng trùng lặp và vẫn hủy bỏ các lỗi khác.
Như một thông báo cuối cùng: bài đăng này được lấy cảm hứng từ Xaprb. Tôi cũng khuyên bạn nên tham khảo bài đăng khác của mình về cách viết các truy vấn SQL linh hoạt.