web-dev-qa-db-ja.com

ID列をINTからBIGINTに変更する

主キーでもあるID列を持つテーブルがあります。現在、5000万行あり、identity列の最高値は148,921,803です。テーブルには多くのDELETEsとINSERTSが実行されているため、値が高くなっています。

さらに行を追加できるように、データタイプをINTからBIGINTに変更します。 PK列への参照がないことに注意してください。

最小限のダウンタイムでこれを行うための最良の方法は何ですか? 2つのオプションがあります。

  1. PKをドロップして列を変更します。または
  2. 説明されているように、copy-drop-renameメソッド here
9
Felix Pamittan

ID列に定義された主キーがあるため、この列を直接変更することはできません。

質問で述べた両方のアプローチを使用でき、ダウンタイムはサーバーのパフォーマンスとそのテーブル内の行数に依存します。

  1. PKをドロップして列を変更します。または

最初にPKをドロップします

/****** Object: DROP Index [PK_DatabaseLog_DatabaseLogID]******/

ALTER TABLE [dbo].[TableName] DROP CONSTRAINT [PK_TableName_ID]
GO

列を変更

ALTER TABLE [dbo].[TableName] ALTER COLUMN [dbo.ID] BIGINT

主キーを追加

/****** Object: ADD Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] ADD  CONSTRAINT [PK_TableName_ID] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)

このアプローチは通常、それほど時間はかかりません。私の環境では、500万行を超える大きなテーブルで数秒かかります。

  1. 説明されているように、copy-drop-renameメソッド

このアプローチも使用できます。ただし、このアプローチでは、テーブルを同期する必要があるため、アプローチ1よりも多くのダウンタイムが必要です。

7
Shashank Tiwari

Aaron Bertrandは、このトピックについて4部構成のシリーズを始めています。

IDENTITY列の拡大による影響の最小化–パート1

絶対にbigintに移動する必要があり、ダウンタイムを最小限に抑え、計画に十分な時間がある場合、彼が文書化するアプローチ パート4 は次のとおりです。

非常に高いレベルでのアプローチは、シャドウテーブルのセットを作成することです。ここで、すべての挿入はテーブルの新しいコピー(より大きなデータ型)に向けられ、2つのテーブルセットの存在は透過的です。アプリケーションとそのユーザーに可能な限り。

より詳細には、アーロンは言う:

  1. 適切なデータ型を使用して、テーブルのシャドウコピーを作成します。
  2. ストアドプロシージャ(またはアドホックコード)を変更して、パラメータにbigintを使用します。 (これには、ローカル変数、一時テーブルなど、パラメーターリスト以外の変更が必要になる場合がありますが、ここではそうではありません。)
  3. 古いテーブルの名前を変更し、古いテーブルと新しいテーブルを結合する名前でビューを作成します。
    • これらのビューには、DML操作を適切なテーブルに適切に送信するためのトリガーの代わりに、移行中にデータを変更できるようにします。
    • これには、インデックス付きビューからSCHEMABINDINGを削除する必要があり、既存のビューに新しいテーブルと古いテーブルを結合する必要があります。また、変更するSCOPE_IDENTITY()に依存するプロシージャも必要です。
  4. 古いデータをチャンクで新しいテーブルに移行します。
  5. 以下から構成されるクリーンアップ:
    • 一時ビューを削除します(INSTEAD OFトリガーが削除されます)。
    • 新しいテーブルの名前を元の名前に戻します。
    • SCOPE_IDENTITY()に戻るようにストアドプロシージャを修正します。
    • 古い空のテーブルを削除します。
    • SCHEMABINDINGをインデックス付きビューに戻し、クラスター化インデックスを再作成します。
6
Paul White 9