การอัปเดตคีย์หลัก MySQL


104

ฉันมีตารางที่user_interactionsมี 4 คอลัมน์:

 user_1
 user_2
 type
 timestamp

คีย์หลักคือ(user_1,user_2,type)
และฉันต้องการเปลี่ยนเป็น(user_2,user_1,type)

สิ่งที่ฉันทำคือ:

drop primary key ...  
add primary key (user_2,user_1,type)...

และ voila ...

ปัญหาคือฐานข้อมูลอยู่บนเซิร์ฟเวอร์

ดังนั้นก่อนที่ฉันจะสามารถอัปเดตคีย์หลักได้มีรายการที่ซ้ำกันจำนวนมากได้พุ่งเข้ามาและมีการคืบคลานเข้ามาอย่างต่อเนื่อง

จะทำอย่างไร?

สิ่งที่ฉันต้องการทำตอนนี้คือลบรายการที่ซ้ำกันและเก็บรายการที่ซ้ำกันไว้ล่าสุดtimestamp(ซึ่งเป็นคอลัมน์ในตาราง)

จากนั้นอัปเดตคีย์หลักอีกครั้ง


16
จู่ๆฉันก็รู้สึกแย่กับทุก DBA ที่ฉันสาปแช่งภายใต้ลมหายใจ ...
Ignacio Vazquez-Abrams

5
ในครั้งต่อไปให้เพิ่มคีย์เฉพาะที่มีคอลัมน์เดียวกันกับคีย์หลักจากนั้นอัปเดตคีย์หลัก
knittl

1
@Ignacio มันอยู่บนเซิร์ฟเวอร์ แต่เป็นเซิร์ฟเวอร์สำรองข้อมูลสำรอง :-) ฉันไม่ใช่ DBA แต่ฉันจะไม่ลองสิ่งนี้บนเซิร์ฟเวอร์สดจริงๆ :-)
simplfuzz

1
@knittl ใช่นั่นคือสิ่งที่ฉันคิดไว้ตอนนี้ดึกมากแล้ว :-)
simplfuzz

4
@pixeline: เป็นคีย์หลักแบบผสม
Ignacio Vazquez-Abrams

คำตอบ:


233

ครั้งต่อไปให้ใช้คำสั่ง "แก้ไขตาราง" เดียวเพื่ออัปเดตคีย์หลัก

alter table xx drop primary key, add primary key(k1, k2, k3);

วิธีแก้ไข:

create table fixit (user_2, user_1, type, timestamp, n, primary key( user_2, user_1, type) );
lock table fixit write, user_interactions u write, user_interactions write;

insert into fixit 
select user_2, user_1, type, max(timestamp), count(*) n from user_interactions u 
group by user_2, user_1, type
having n > 1;

delete u from user_interactions u, fixit 
where fixit.user_2 = u.user_2 
  and fixit.user_1 = u.user_1 
  and fixit.type = u.type 
  and fixit.timestamp != u.timestamp;

alter table user_interactions add primary key (user_2, user_1, type );

unlock tables;

การล็อกควรหยุดการอัปเดตเพิ่มเติมในขณะที่คุณกำลังดำเนินการนี้ เห็นได้ชัดว่าจะใช้เวลานานแค่ไหนขึ้นอยู่กับขนาดโต๊ะของคุณ

ปัญหาหลักคือหากคุณมีข้อมูลซ้ำกับการประทับเวลาเดียวกัน


11

หากคีย์หลักเป็นค่า auto_increment คุณต้องลบการเพิ่มอัตโนมัติจากนั้นวางคีย์หลักจากนั้นเพิ่มการเพิ่มอัตโนมัติอีกครั้ง

ALTER TABLE `xx`
MODIFY `auto_increment_field` INT, 
DROP PRIMARY KEY, 
ADD PRIMARY KEY (new_primary_key);

จากนั้นเพิ่มการเพิ่มอัตโนมัติกลับเข้าไป

ALTER TABLE `xx` ADD INDEX `auto_increment_field` (auto_increment_field),
MODIFY `auto_increment_field` int auto_increment;

จากนั้นตั้งค่าการเพิ่มอัตโนมัติกลับเป็นค่าก่อนหน้า

ALTER TABLE `xx` AUTO_INCREMENT = 5;

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.