Memperbarui kunci utama MySQL

103

Saya memiliki tabel user_interactionsdengan 4 kolom:

 user_1
 user_2
 type
 timestamp

Kunci utama adalah (user_1,user_2,type)
dan saya ingin mengubah ke(user_2,user_1,type)

Jadi yang saya lakukan adalah:

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

dan voila ...

Masalahnya adalah database itu hidup di server.

Jadi sebelum saya dapat memperbarui kunci utama, banyak duplikat sudah masuk, dan mereka terus menyusup.

Apa yang harus dilakukan?

Yang ingin saya lakukan sekarang adalah menghapus duplikat dan menyimpan yang terbaru timestamp(yaitu kolom di tabel).

Dan kemudian perbarui kunci utama lagi.

simplfuzz
sumber
16
Saya tiba-tiba merasa tidak enak untuk setiap DBA yang saya kutuk pelan ...
Ignacio Vazquez-Abrams
5
lain kali tambahkan kunci unik dengan kolom yang sama dengan kunci utama, lalu perbarui kunci utama
knittl
1
@Ignacio, itu langsung di server, tapi itu server cadangan-cadangan :-). Saya bukan DBA, tetapi saya tidak akan mencoba hal ini di server yang
SUNGGUH LANGSUNG
1
@knittl, ya itulah yang saya pikirkan sekarang, sangat terlambat :-)
simplfuzz
4
@ piksel: Ini adalah kunci utama majemuk.
Ignacio Vazquez-Abrams

Jawaban:

231

Lain kali, gunakan satu pernyataan "alter table" untuk memperbarui kunci utama.

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

Untuk memperbaiki berbagai hal:

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;

Kunci harus menghentikan pembaruan lebih lanjut yang masuk saat Anda melakukan ini. Berapa lama ini tergantung pada ukuran meja Anda.

Masalah utamanya adalah jika Anda memiliki beberapa duplikat dengan stempel waktu yang sama.

Martin
sumber
11

Jika kunci utama kebetulan adalah nilai auto_increment, Anda harus menghapus kenaikan otomatis, lalu jatuhkan kunci utama lalu tambahkan kembali kenaikan otomatis

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

lalu tambahkan kembali kenaikan otomatis

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

lalu setel kenaikan otomatis kembali ke nilai sebelumnya

ALTER TABLE `xx` AUTO_INCREMENT = 5;
frazras.dll
sumber
2

Anda juga dapat menggunakan IGNOREkata kunci, contoh:

 update IGNORE table set primary_field = 'value'...............
Sarfraz
sumber