Обновление первичного ключа MySQL
У меня есть таблица 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)...
и вуаля...
Проблема в том, что база данных находится в режиме реального времени на сервере.
Итак, прежде чем я смог обновить первичный ключ, многие дубликаты уже вошли, и они постоянно ползут.
Что делать?
Теперь я хочу удалить дубликаты и сохранить их с последним timestamp
(который является столбцом в таблице).
И затем как-нибудь обновите первичный ключ снова.
Ответы
Ответ 1
В следующий раз для обновления первичного ключа используйте один оператор "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;
Блокировка должна останавливать дальнейшие обновления, пока вы это делаете. Как долго это занимает, очевидно, зависит от размера вашей таблицы.
Основная проблема заключается в том, что у вас есть дубликаты с одинаковой меткой времени.
Ответ 2
Если основным ключом является значение 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;
Ответ 3
Вы также можете использовать ключевое слово IGNORE
, например:
update IGNORE table set primary_field = 'value'...............