18 ตุลาคม 2550
ในการเริ่มต้น: จาก MySQL ล่าสุดไม่สามารถใช้ไวยากรณ์ที่ปรากฏในชื่อเรื่องได้ แต่มีวิธีง่าย ๆ หลายวิธีในการบรรลุสิ่งที่คาดหวังโดยใช้ฟังก์ชันการทำงานที่มีอยู่
มีวิธีแก้ปัญหา 3 วิธีที่เป็นไปได้: ใช้ INSERT IGNORE, REPLACE หรือ INSERT ... ในการอัปเดต KEY ซ้ำซ้อน
ลองนึกภาพเรามีตาราง:
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;
ทีนี้ลองนึกภาพว่าเรามีเมตาดาต้าไพพ์ไลน์แบบอัตโนมัติที่นำเข้าทรานสคริปต์ข้อมูลจาก Ensembl และด้วยเหตุผลหลายประการไพพ์ไลน์อาจเสียในทุกขั้นตอนของการดำเนินการ ดังนั้นเราต้องมั่นใจว่ามีสองสิ่ง:
การเรียกใช้งานท่อซ้ำหลายครั้งจะไม่ทำลายฐานข้อมูลของเรา
การประมวลผลซ้ำ ๆ จะไม่ตายเนื่องจากข้อผิดพลาด 'คีย์หลักที่ซ้ำกัน'
วิธีที่ 1: ใช้ REPLACE
มันง่ายมาก:
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
หากมีบันทึกอยู่มันจะถูกเขียนทับ หากยังไม่มีอยู่จะถูกสร้างขึ้น อย่างไรก็ตามการใช้วิธีนี้ไม่ได้มีประสิทธิภาพสำหรับกรณีของเรา: เราไม่จำเป็นต้องเขียนทับระเบียนที่มีอยู่มันก็แค่ข้ามไป
วิธีที่ 2: ใช้ INSERT IGNORE ง่ายมากเช่นกัน:
INSERT IGNORE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
ที่นี่หาก 'ensembl_transcript_id' มีอยู่ในฐานข้อมูลแล้วจะถูกข้ามแบบเงียบ ๆ (ละเว้น) (เพื่อความแม่นยำมากขึ้นต่อไปนี้เป็นคำพูดจากคู่มืออ้างอิง MySQL:“ หากคุณใช้คำสำคัญ IGNORE ข้อผิดพลาดที่เกิดขึ้นขณะดำเนินการคำสั่ง INSERT จะถือว่าเป็นการเตือนแทนเช่นไม่มี IGNORE แถวที่ซ้ำดัชนี UNIQUE ที่มีอยู่เดิม หรือค่าคีย์หลักในตารางทำให้เกิดข้อผิดพลาดซ้ำกันของคีย์และคำสั่งจะถูกยกเลิก”) หากยังไม่มีการบันทึกข้อมูลมันจะถูกสร้างขึ้น
วิธีที่สองนี้มีจุดอ่อนหลายประการรวมถึงการไม่ทำแท้งของแบบสอบถามในกรณีที่มีปัญหาอื่น ๆ เกิดขึ้น (ดูคู่มือ) ดังนั้นจึงควรใช้หากทดสอบก่อนหน้านี้โดยไม่มีคำหลัก IGNORE
วิธีที่ 3: ใช้ INSERT ... ในการอัปเดตคีย์ซ้ำกัน:
ตัวเลือกที่สามคือการใช้INSERT … ON DUPLICATE KEY UPDATE
ไวยากรณ์และในส่วน UPDATE ไม่ได้ทำอะไรเลยการดำเนินการที่ไม่มีความหมาย (ว่างเปล่า) เช่นการคำนวณ 0 + 0 (Geoffray แนะนำให้ทำการกำหนด id = id สำหรับเครื่องมือเพิ่มประสิทธิภาพ MySQL เพื่อละเว้นการดำเนินการนี้) ข้อดีของวิธีนี้คือการละเว้นเหตุการณ์สำคัญที่ซ้ำกันเท่านั้นและยังคงยกเลิกข้อผิดพลาดอื่น ๆ
เป็นการแจ้งให้ทราบล่วงหน้า: โพสต์นี้ได้รับแรงบันดาลใจจาก Xaprb ฉันยังแนะนำให้ปรึกษาโพสต์อื่น ๆ ของเขาเกี่ยวกับการเขียนแบบสอบถาม SQL ที่ยืดหยุ่น