Обработка ошибок и целостность данных при изменении схемы таблицы - PullRequest
1 голос
/ 15 июня 2009

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

Ранее мы просматривали временную таблицу с новой схемой, а затем отбрасывали оригинал и переименовывали временную таблицу, но я надеюсь значительно ускорить это, используя вместо этого ALTER table ....

У меня вопрос, какие вопросы целостности данных и обработки ошибок мне нужно учитывать? Должен ли я включить все изменения в таблицу в транзакции (и если да, то как?) Или СУБД гарантирует атомарность и целостность операции ALTER?

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

Нам нужно ориентироваться на SQLServer 2005 и Oracle, но, очевидно, я могу добавить условный код, если они требуют разных подходов.

Ответы [ 4 ]

3 голосов
/ 15 июня 2009

Комментарии только для Oracle:

  • Изменения таблицы - это DDL, поэтому концепция транзакции неприменима - каждый оператор DDL блокирует таблицу на время операции и либо успешно, либо с ошибкой.

  • Добавление (обнуляемое!) Столбцов или переименование существующих столбцов - это относительно легкий процесс, который не должен создавать проблем при получении блокировки таблицы.

  • Если вы добавляете / изменяете ограничения (либо NOT NULL, либо другие более сложные проверочные ограничения), Oracle будет проверять существующие данные для проверки ограничений, если вы не добавите предложение ENABLE NOVALIDATE в ограничение DDL. Проверка существующих данных может быть длительным процессом для больших таблиц.

  • Если вы создаете сценарий обновления для запуска в виде сценария SQL * Plus, избавьте себя от множества головных болей, используя директиву всякий раз, когда sqlerror exit sql.sqlcode, чтобы прервать выполнение сценария при первом сбое. облегчить обзор частично выполненных обновлений.

  • Если обновление должно выполняться в работающей системе, где вы не можете ни контролировать транзакции, ни позволить себе их пропустить, рассмотрите возможность использования пакета Oracle DBMS_REDEFINITION, который автоматически создает временную конфигурацию временных таблиц и триггеры для захвата входных данных. Полет транзакций при переопределении таблицы в «фоновом режиме». Предупреждение - много работы и крутая кривая обучения для этой опции.

1 голос
/ 15 июня 2009

В прошлом мне приходилось делать подобные изменения, и я всегда был очень параноидален в отношении потери данных. Чтобы уменьшить этот риск, я всегда проводил тонны тестирования с базами данных «песочницы», которые максимально точно отражали целевые базы данных в схеме и данных. Перед развертыванием протестируйте как можно больше процесса, как и в любой другой области приложения.

1 голос
/ 15 июня 2009

Если вы используете SQL Server, тогда операторы ddl являются транзакционными, поэтому включите транзакцию (хотя я не думаю, что это применимо к Oracle).

Мы разделили обновления на отдельные патчи, которые идут с определенной функцией. Какие исправления применяются в таблице database_patch_history, и легко увидеть, какие исправления были применены и как их откатить.

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

0 голосов
/ 15 июня 2009

Если вы резко измените какие-либо типы данных столбцов, например, измените VARCHAR на INT, СУБД будет паниковать, и вы, вероятно, потеряете эти данные. К счастью, в настоящее время СУБД достаточно умны, чтобы выполнять некоторые преобразования типов данных без потери данных, но вы не хотите подвергаться риску их повреждения при внесении изменений.

Вы не должны терять какие-либо данные, переименовывая столбцы, и определенно не будете добавлять новые столбцы, это когда вы перемещаете данные, о которых вы должны беспокоиться.

Во-первых, сделайте резервную копию всей таблицы, как схемы, так и данных, так что, как только вы заметите, вы сможете вернуться к предыдущей схеме. Во-вторых, посмотрите на изменения, которые вы пытаетесь внести, посмотрите, насколько они радикальны - попытайтесь точно определить, что нужно изменить. Если вы выполняете преобразования типов данных, сначала поместите эти данные в таблицу промежуточных сообщений с 3 столбцами, внешним ключом (идентификатором или любым другим, чтобы вы могли найти строку), старыми данными и новым столбцом. Затем либо напрямую перенесите старые данные в новый столбец, либо преобразуйте их на уровне приложения.

Когда все в правильных типах и все прошло успешно, запустите операторы ALTER и снова заполните базу данных! Это достаточно просто сделать, просто нужен логический мыслительный процесс.

...