Какой хороший способ добавить ПЕРВИЧНЫЙ КЛЮЧ в большую таблицу InnoDB?

8

У меня есть таблица с около 30 миллионов строк в MySQL 5.5 с использованием механизма хранения InnoDB. Эта таблица имеет внешний ключ, который ссылается на другую таблицу с примерно 3 миллионами строк.

Я хочу добавить первичный ключ в большую таблицу, но не уверен, как лучше это сделать. Там нет никакого существующего столбца (или набора столбцов), который я могу использовать для этого, так как я должен поступить об этом?

Я видел некоторые ссылки на внутренний идентификатор записи InnoDB, но не нашел, если это доступно.

В противном случае, возможно, мне потребуется сбросить данные и перезагрузить данные, добавив идентификатор вручную.

Спасибо.

Водин
источник
Является ли их комбинация клавиш в таблице уникальной? Если так, то первичный ключ из нескольких столбцов может иметь смысл.
Джастин Даринг
К сожалению, такого составного ключа не было. В противном случае я согласен, что это имеет смысл. Я отредактировал пост, чтобы уточнить, что это было невозможно.
Водин

Ответы:

7

это может быть неправильный путь, но ..

не могли бы вы просто изменить структуру таблицы,

добавить столбец первичного ключа в таблицу

тогда...

написать быстрый скрипт, чтобы пройти всю таблицу

добавить автоинкрементное значение в новый столбец?

Патрик
источник
2
Спасибо за предложение. Я думаю, что мне нужно было бы добавить столбец как не-первичный ключ, а затем преобразовать его в первичный ключ, но я на самом деле просто случайно обнаружил, что при тестировании небольшой таблицы добавляется столбец AUTO_INCREMENT (как первичный ключ) автоматически заполняет идентификаторы. Предполагалось, что это просто даст мне ошибку, поэтому я думаю, что это ответ.
Водин
если база данных интенсивно используется, вы можете протестировать ее на некритической таблице, чтобы убедиться, что она не блокируется в течение длительного времени
Патрик
@ Патрик, спасибо за предостережение. База данных в настоящее время не используется, и я полностью ожидаю, что это заблокирует таблицу на долгое время.
Wodin
1
Я сделал, ALTER TABLE blah ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;и это заняло 2 часа и 18 минут :) Я не пытался писать в таблицу в течение этого времени, но чтение работало нормально.
Водин
1
@ Wodin Вау, это долгое время для команды изменения таблицы. рад, что это сработало для вас.
Патрик
3

Вот как я бы подошел к этому:

  1. Создать новую таблицу с желаемой структурой, включающей ваш ПЕРВИЧНЫЙ КЛЮЧ с AUTO_INCREMENT и, возможно, еще одно проиндексированное поле.
  2. Возьмите простой, чтобы остановить весь трафик.
  3. Подтвердите, что у вас есть законная резервная копия ваших данных.
  4. Скопируйте все свои строки из существующей таблицы в таблицу назначения, используя AUTO INCREMENT для создания своих идентификаторов. * например, INSERT INTO target_table (col1, col2 и т. д.) SELECT (col1, col2 и т. д.) FROM origin_table; *
  5. Проверьте правильность данных в новой таблице.
  6. ПЕРЕИМЕНОВАТЬ старую таблицу origin_table_BAK.
  7. RENAME target_table в origin_table.
  8. Тест дыма ваше приложение.
  9. Открыть обратно в трафик.
  10. После следующей резервной копии удалите origin_table_BAK.

* Примечание. Если исходной таблицей является InnoDB, ограничения внешнего ключа будут сохранены и сохранятся после переименования. Так что вам придется внести изменения, чтобы исправить это.

randomx
источник
3
Если вам нужно сделать это вживую, выполните шаги 6 и 7 в одном RENAME, сделав его атомарным. RENAME TABLE real_name TO старый, новый TO real_name;
Рик Джеймс