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