SQL Server - Изменение таблицы против удаления и создания
-
28-09-2020 - |
Вопрос
Наша база данных - SQL Server 2008 R2.У нас есть несколько таблиц, в которых есть несколько столбцов varchar(500), которые я хочу переключить на datetime2 или bigint.Я могу гарантировать, что все данные в переключаемых столбцах действительны для соответствующего типа.Изменения столбцов действительно влияют на индексы, но не на ключи.
Обсуждая это с коллегами, мы пришли к двум подходам к решению проблемы.Оба эти действия будут выполняться с помощью скриптов T-Sql.
- Создайте временную таблицу с помощью select into, удалите старую таблицу и воссоздайте таблицу с соответствующими типами данных.Воссоздайте индексы заново.
- Измените текущую таблицу/типы данных с помощью
ALTER TABLE x ALTER COLUMN Y datetime2
а затем перестроить или воссоздать заново индексы.
Поскольку я уверен, что данные будут преобразованы чисто, я склоняюсь к # 2.Мой коллега и друг-администратор базы данных предпочитают # 1, но мой коллега не может вспомнить, почему они обучали его таким образом.Друг администратора базы данных в отпуске, поэтому я не спрашивал его почему.
Может ли кто-нибудь дать представление о том, какой вариант, по их мнению, лучше и почему?В конечном счете, это мое решение, и мне интересно, почему # 1 предпочтительнее # 2?
Решение
Недавно я сделал это в своей организации, где мы хотели обработать таблицу с более чем миллиардом строк.
Вся заслуга в разработке идеи принадлежит Аарону Бертрану, и она взята из его записи в блоге Трюковые выстрелы :Переключатель схемы-A-Roo
Протестируйте приведенный ниже процесс на небольшом столе и почувствуйте себя комфортно, прежде чем выполнять его в PROD.
- создайте 2 схемы
fake
иshadow
с разрешенияdbo
. - Создайте таблицу со столбцами и типами данных, которые вы хотите использовать
shadow
схема, например.create table shadow.Correct_Table ...
- Вставьте данные и создайте все индексы, которые есть в исходной таблице в
shadow
таблица схемы. - Таким образом, у вас есть идентичные копии таблицы с данными и индексами, но они находятся в разных схемах (логически разделены).
- После завершения обновите статистику в таблице с помощью
shadow
схема. Переключение схем (это операция с метаданными, и она выполняется чрезвычайно быстро)
--- ALTER SCHEMA TargetSchema TRANSFER SourceSchema.TableName; BEGIN TRANSACTION; ALTER SCHEMA fake TRANSFER dbo.original_table; ALTER SCHEMA dbo TRANSFER shadow.Correct_Table; COMMIT TRANSACTION; ALTER SCHEMA shadow TRANSFER fake.Lookup;
Сделайте последнюю проверку, чтобы убедиться, что все прошло так, как планировалось.Вы должны сделать
select count(1) from dbo.Correct_table
Как только шаг 7 будет подтвержден и вы будете довольны, отбросьте
shadow.table
,shadow
схема иfake
схема по мере очистки.
Другие советы
Вот как я вижу это.
<Сильные> плюсы для # 1
- .
- Поскольку вы используете отдельную таблицу, что ваш производственный стол остается в использовании, пока вы не сделаете. Нет замков на нем (за пределами необходимых для чтения данных).
- Это также идет с тем, что сказал @aaronbertrand: вы можете сделать это по частям, тестировать и т. Д.
- Вы можете изменить порядок столбца по необходимости
<Сильные> плюсы для # 2
- .
- Это все или ничего не работает. Нет никаких шансов, которые вы собираетесь потерять данные, которые были вставлены / изменены в оригинальной таблице, пока вы не смотрели.
- Любые разрешения, которые специально назначаются на объект, сохраняются. Если вы используете № 1, вы должны убедиться, что вы скрипте и применяете их.
Все это говорится, что я обычно использую # 2 для небольших таблиц или когда я могу получить отключение (всегда делайте резервную копию перед рукой) и # 1, если я не могу получить максимальный отключение или я должен Переустановите заказ на заказ столбца и т. Д. Если я собираюсь сделать # 1, я, как правило, буду генерировать сценарий через графический интерфейс, а затем внимательно просматривать его, прежде чем запустить его.
Будьте осторожны с опцией удаления и повторного создания:это может привести к тому, что sys.depends окажется в странном состоянии и вызовет проблемы для кэшированных планов, в которых меняется порядок или тип столбцов.
Вам также нужно будет предпринять шаги для сохранения любых разрешений на уровне объекта, так как они будут потеряны в процессе DROP
и не воссоздается автоматически при последующем CREATE
.
ALTER TABLE
это более чистый вариант, ИМО, но убедитесь, что вы тщательно протестировали, прежде чем делать это в рабочей среде, как для того, чтобы убедиться, что после этого все хорошо, так и для того, чтобы убедиться, что вы знаете, сколько времени займут операции (для таблицы с большим количеством строк это может занять довольно много времени).
Мой коллега оказался поиском статьи о том, что он ссылался на: http:// www.nigelrivett.net/sqladmin/altertableProblems.html .Прочитав это и познакомившись на нашей годовой конец отчетности, мы решили не внести изменения в типы столбцов и пересматривают это в следующие пару месяцев.Я думаю, что после прочтения статьи я могу просто пойти с методом Drop / Create.
Спасибо всем за отзыв об этом.Многие интересные подходы к рассмотрению, когда мы решили продвинуться вперед.