MySQLの主キーの更新


103

user_interactions4つの列を持つテーブルがあります。

 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)...

そして出来上がり...

問題は、データベースがサーバー上にあることです。

したがって、主キーを更新する前に、すでに多くの重複が侵入しており、それらは継続的に侵入しています。

何をすべきか?

私が今したいのは、重複を削除して最新のものtimestamp(テーブルの列)を保持することです。

そして、どういうわけか、もう一度主キーを更新します。


16
私は自分の息の中で呪ったすべてのDBAに突然気分が悪くなりました...
Ignacio Vazquez-Abrams

5
次回、主キーと同じ列を持つ一意のキーを追加し、主キーを更新します
knittl

1
@Ignacio、それはサーバー上にありますが、それはバックアップ/バックアップサーバーです:-)。私はDBAではありませんが、実際にライブサーバーでこれを試すことはありません:-)
simplfuzz

1
@knittl、はい、それは私が今思っていることですが、非常に遅いですが:-)
simplfuzz

4
@pixeline:複合主キーです。
Ignacio Vazquez-Abrams、

回答:


231

次回は、単一の「alter table」ステートメントを使用して主キーを更新します。

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;

2

IGNOREキーワードも使用できます。例:

 update IGNORE table set primary_field = 'value'...............
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.