การลบรายการที่ซ้ำกันในตาราง MySQL เป็นปัญหาที่พบได้ทั่วไปซึ่งเป็นผลมาจากข้อ จำกัด ที่ขาดหายไปเพื่อหลีกเลี่ยงรายการที่ซ้ำกันก่อนถึงมือ แต่ปัญหาที่พบบ่อยนี้มักจะมาพร้อมกับความต้องการที่เฉพาะเจาะจง ... ที่ต้องมีวิธีการเฉพาะ วิธีการควรแตกต่างกันไปขึ้นอยู่กับขนาดของข้อมูลรายการที่ซ้ำที่ควรเก็บไว้ (โดยทั่วไปเป็นรายการแรกหรือรายการสุดท้าย) ไม่ว่าจะมีดัชนีที่จะเก็บไว้หรือไม่ว่าเราต้องการดำเนินการเพิ่มเติมใด ๆ การดำเนินการกับข้อมูลที่ซ้ำกัน
นอกจากนี้ยังมีลักษณะเฉพาะบางอย่างใน MySQL เช่นไม่สามารถอ้างอิงตารางเดียวกันในสาเหตุ FROM เมื่อดำเนินการตาราง UPDATE (จะทำให้เกิดข้อผิดพลาด MySQL # 1093) ข้อ จำกัด นี้สามารถเอาชนะได้โดยใช้การสืบค้นภายในที่มีตารางชั่วคราว (ตามที่แนะนำในวิธีการบางอย่างข้างต้น) แต่แบบสอบถามภายในนี้จะทำงานได้ไม่ดีเป็นพิเศษเมื่อจัดการกับแหล่งข้อมูลขนาดใหญ่
อย่างไรก็ตามมีวิธีการที่ดีกว่าในการลบรายการที่ซ้ำกันซึ่งทั้งมีประสิทธิภาพและเชื่อถือได้และสามารถปรับให้เข้ากับความต้องการที่แตกต่างกันได้อย่างง่ายดาย
แนวคิดทั่วไปคือการสร้างตารางชั่วคราวใหม่มักจะเพิ่มข้อ จำกัด ที่ไม่ซ้ำกันเพื่อหลีกเลี่ยงการซ้ำซ้อนเพิ่มเติมและเพื่อแทรกข้อมูลจากตารางเดิมของคุณลงในตารางใหม่ในขณะที่ดูแลข้อมูลที่ซ้ำกัน วิธีนี้อาศัยการสืบค้น MySQL INSERT ง่าย ๆ สร้างข้อ จำกัด ใหม่เพื่อหลีกเลี่ยงการซ้ำซ้อนและข้ามความจำเป็นในการใช้การสืบค้นภายในเพื่อค้นหารายการที่ซ้ำกันและตารางชั่วคราวที่ควรเก็บไว้ในหน่วยความจำ
นี่คือวิธีที่จะสามารถทำได้ เนื่องจากเรามีพนักงานตารางโดยมีคอลัมน์ต่อไปนี้:
employee (id, first_name, last_name, start_date, ssn)
เพื่อลบแถวที่มีคอลัมน์ssn ที่ซ้ำกันและเก็บเฉพาะรายการแรกที่พบกระบวนการต่อไปนี้สามารถติดตามได้:
-- create a new tmp_eployee table
CREATE TABLE tmp_employee LIKE employee;
-- add a unique constraint
ALTER TABLE tmp_employee ADD UNIQUE(ssn);
-- scan over the employee table to insert employee entries
INSERT IGNORE INTO tmp_employee SELECT * FROM employee ORDER BY id;
-- rename tables
RENAME TABLE employee TO backup_employee, tmp_employee TO employee;
คำอธิบายทางเทคนิค
- Line # 1 สร้างตารางtmp_eployeeใหม่ที่มีโครงสร้างเหมือนกับตารางพนักงาน
- Line # 2 เพิ่มข้อ จำกัด UNIQUE ให้กับตารางtmp_eployeeใหม่เพื่อหลีกเลี่ยงการซ้ำซ้อนเพิ่มเติม
- บรรทัดที่ 3 สแกนตารางพนักงานเดิมโดยใช้รหัสการแทรกรายการพนักงานใหม่ลงในตารางtmp_eployeeใหม่ในขณะที่ละเว้นรายการซ้ำ
- บรรทัดที่ # 4 เปลี่ยนชื่อตารางเพื่อให้ตารางพนักงานใหม่เก็บรายการทั้งหมดโดยไม่มีรายการที่ซ้ำกันและสำเนาสำรองของข้อมูลเดิมจะถูกเก็บไว้ในตารางbackup_employee
⇒เมื่อใช้วิธีนี้การลงทะเบียน 1.6M จะถูกแปลงเป็น 6k ในเวลาน้อยกว่า 200 วินาที
Chetanทำตามขั้นตอนนี้คุณสามารถลบรายการที่ซ้ำกันทั้งหมดได้อย่างรวดเร็วและง่ายดายและสร้างข้อ จำกัด UNIQUE โดยการเรียกใช้:
CREATE TABLE tmp_jobs LIKE jobs;
ALTER TABLE tmp_jobs ADD UNIQUE(site_id, title, company);
INSERT IGNORE INTO tmp_jobs SELECT * FROM jobs ORDER BY id;
RENAME TABLE jobs TO backup_jobs, tmp_jobs TO jobs;
แน่นอนว่ากระบวนการนี้สามารถแก้ไขเพิ่มเติมเพื่อปรับให้เข้ากับความต้องการที่แตกต่างกันเมื่อทำการลบข้อมูลที่ซ้ำกัน ตัวอย่างบางส่วนปฏิบัติตาม
✔ความหลากหลายในการเก็บรักษารายการสุดท้ายแทนรายการแรก
บางครั้งเราจำเป็นต้องเก็บรายการที่ซ้ำกันครั้งล่าสุดแทนที่จะเป็นรายการแรก
CREATE TABLE tmp_employee LIKE employee;
ALTER TABLE tmp_employee ADD UNIQUE(ssn);
INSERT IGNORE INTO tmp_employee SELECT * FROM employee ORDER BY id DESC;
RENAME TABLE employee TO backup_employee, tmp_employee TO employee;
- ในบรรทัด # 3 ส่วนคำสั่ง ORDER BY idทำให้ ID สุดท้ายของลำดับความสำคัญเหนือส่วนที่เหลือ
✔ความหลากหลายสำหรับการทำงานบางอย่างกับรายการที่ซ้ำกันตัวอย่างเช่นรักษาจำนวนที่ซ้ำกันที่พบ
บางครั้งเราจำเป็นต้องทำการประมวลผลเพิ่มเติมในรายการที่ซ้ำที่พบ (เช่นการนับซ้ำ)
CREATE TABLE tmp_employee LIKE employee;
ALTER TABLE tmp_employee ADD UNIQUE(ssn);
ALTER TABLE tmp_employee ADD COLUMN n_duplicates INT DEFAULT 0;
INSERT INTO tmp_employee SELECT * FROM employee ORDER BY id ON DUPLICATE KEY UPDATE n_duplicates=n_duplicates+1;
RENAME TABLE employee TO backup_employee, tmp_employee TO employee;
- ในบรรทัด # 3 คอลัมน์ใหม่n_duplicatesจะถูกสร้างขึ้น
- ในบรรทัด # 4, INSERT INTO ... ON DUPLICATE KEY UPDATEใช้เพื่อดำเนินการอัปเดตเพิ่มเติมเมื่อพบซ้ำ (ในกรณีนี้เพิ่มตัวนับ) INSERT INTO ... ON DUPLICATE KEY UPDATEสามารถ ใช้เพื่อดำเนินการอัพเดตประเภทต่าง ๆ สำหรับรายการซ้ำที่พบ
✔ความผันแปรสำหรับการสร้างรหัสฟิลด์ที่เพิ่มขึ้นอัตโนมัติ
บางครั้งเราใช้เขตข้อมูลที่เพิ่มขึ้นอัตโนมัติและเพื่อให้ดัชนีมีขนาดกะทัดรัดที่สุดเท่าที่จะทำได้เราสามารถใช้ประโยชน์จากการลบข้อมูลที่ซ้ำกันเพื่อสร้างฟิลด์ที่เพิ่มขึ้นอัตโนมัติในตารางชั่วคราวใหม่
CREATE TABLE tmp_employee LIKE employee;
ALTER TABLE tmp_employee ADD UNIQUE(ssn);
INSERT IGNORE INTO tmp_employee SELECT (first_name, last_name, start_date, ssn) FROM employee ORDER BY id;
RENAME TABLE employee TO backup_employee, tmp_employee TO employee;
- บนบรรทัด # 3 แทนที่จะเลือกเขตข้อมูลทั้งหมดในตารางเขตข้อมูล id จะถูกข้ามเพื่อให้โปรแกรมฐานข้อมูลสร้างขึ้นใหม่โดยอัตโนมัติ
✔รูปแบบเพิ่มเติม
การปรับเปลี่ยนเพิ่มเติมจำนวนมากยังสามารถทำได้ขึ้นอยู่กับพฤติกรรมที่ต้องการ เป็นตัวอย่างแบบสอบถามต่อไปนี้จะใช้ตารางชั่วคราวที่สองนอกเหนือจาก 1) เก็บรายการสุดท้ายแทนรายการแรก และ 2) เพิ่มตัวนับบนรายการซ้ำที่พบ 3) สร้างรหัสฟิลด์ที่เพิ่มขึ้นอัตโนมัติอีกครั้งในขณะที่รักษาลำดับการเข้าใช้เหมือนเดิมกับข้อมูลเดิม
CREATE TABLE tmp_employee LIKE employee;
ALTER TABLE tmp_employee ADD UNIQUE(ssn);
ALTER TABLE tmp_employee ADD COLUMN n_duplicates INT DEFAULT 0;
INSERT INTO tmp_employee SELECT * FROM employee ORDER BY id DESC ON DUPLICATE KEY UPDATE n_duplicates=n_duplicates+1;
CREATE TABLE tmp_employee2 LIKE tmp_employee;
INSERT INTO tmp_employee2 SELECT (first_name, last_name, start_date, ssn) FROM tmp_employee ORDER BY id;
DROP TABLE tmp_employee;
RENAME TABLE employee TO backup_employee, tmp_employee2 TO employee;