Каков наилучший способ воссоздать первичный ключ большой таблицы?

#oracle #ddl

#Oracle #ddl

Вопрос:

Мой случай заключается в том, что:

В Oracle DB у меня есть таблица (скажем, table_a) с 2 столбцами только col_a и col_b Количество столбцов невелико, но со многими строками

теперь col_a является первичным ключом, мне нужно добавить к нему новый col (скажем, col_c) и изменить первичный ключ с (col_a) на (col_a, col_c)

Я делаю это следующими способами:

  1. создайте col_c со значением по умолчанию
  2. удалите исходный первичный ключ (col_a), включая индекс
  3. заново создайте первичный ключ (col_a, col_c)

Шаги 1 и 2 хороши и могут быть выполнены в кратчайшие сроки, но для шага 3 он завершается ошибкой через 1x минут с ошибкой, указывающей на отсутствие временного табличного пространства

Есть ли какой-либо способ сделать это лучше, не увеличивая лимит табличного пространства?

Другой способ, который я могу придумать на данный момент (также пытаюсь), — создать новую таблицу (скажем, table_a_temp) с первичным ключом (col_a, col_c). Затем используйте инструкцию «insert select» для копирования данных из table_a в table_a_temp. Наконец, удалите table_a и переименуйте table_a_temp в table_a . Но я боюсь, что архивный журнал повтора может превысить лимит.

Любое предложение высоко ценится.

Комментарии:

1. Я бы создал новую таблицу с опцией NOLOGGING, затем вставил с помощью подсказки APPEND, снова поместил ее в ЖУРНАЛ и поменял местами таблицы с переименованием. Как бы вы заполнили новый col_c , хотя?

2. @MarcoBaldelli Просто хочу убедиться, что я понимаю вашу идею. Сделайте «NOLOGGING» отключающим журнал повтора архива, чтобы не создавался архивный журнал, поэтому не нужно беспокоиться об ограничении пространства журнала. Что касается подсказки APPEND, это просто ускоряет мою вставку, но не слишком сильно влияет на ограничение табличного пространства, потому что оно просто добавляется в конец, а не ищет таблицу свободного пространства между ними. Кроме того, последующая вставка без подсказки ДОБАВЛЕНИЯ все равно заполнит свободное пространство между ними. Наконец, снова включите ведение журнала после вставки всех записей, сделайте так, чтобы архивный журнал повтора снова работал.

3. @MarcoBaldelli для заполнения col_c я просто добавляю новый столбец со значением по умолчанию, чтобы он заполнялся автоматически. После определенной версии в Oracle должна быть некоторая оптимизация, чтобы она была действительно быстрой за несколько секунд.

4. это известно как «ВСТАВКА прямого пути». Если вы решите использовать NOLOGGING, вам следует впоследствии создать резервную копию базы данных. Вы можете найти более подробную информацию на достопочтенном веб-сайте Ask Tom .

5. Просто в качестве дополнительного замечания, у вас не возникло бы этой проблемы, если бы вы следовали принципам разумного проектирования. PK должно быть произвольным значением (часто с использованием генератора последовательностей), которое не имеет никакого делового значения. Затем, если у вас есть другие столбцы, которые должны быть «похожи» на PK, просто поместите на них уникальный индекс.

Ответ №1:

Вы можете экспортировать данные, очистить таблицу, создать индекс, отсортировать экспортированные данные, а затем импортировать их обратно, воспользовавшись предложением SORTED INDEXES в SQL * Loader .

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