巨大なファクト テーブルがあり、新しいディメンションを追加したい場合は、次のように実行できます。
BEGIN TRANSACTION
ALTER TABLE [GiantFactTable]
ADD NewDimValueId INT NOT NULL
CONSTRAINT [temp_DF_NewDimValueId] DEFAULT (-1)
WITH VALUES -- table is not actually rebuilt!
ALTER TABLE [GiantFactTable]
WITH NOCHECK
ADD CONSTRAINT [FK_GiantFactTable_NewDimValue]
FOREIGN KEY ([NewDimValueId])
REFERENCES [NewDimValue] ([Id])
-- drop the default constraint, new INSERTs will specify a value for NewDimValueId column
ALTER TABLE [GiantFactTable]
DROP CONSTRAINT [temp_DF_NewDimValueId]
COMMIT TRANSACTION
注意: 上記はすべて、テーブルのメタデータを操作するだけであり、テーブルのサイズに関係なく高速である必要があります。GiantFactTable.NewDimValueId
次に、FK に違反しないように、小さなトランザクションをバックフィルするジョブを実行できます。(この時点で、すべての INSERT/UPDATE (バックフィル操作など) は有効になっているため、FK によって検証されますが、「信頼されている」わけではありません)
バックフィルの後、データが一貫していることがわかります。私の質問は、SQL エンジンもどのように対応できるようになるかということです。テーブルをオフラインにすることなく。
このコマンドは FK を信頼済みにしますが、スキーマ変更 (Sch-M) ロックが必要であり、テーブルをオフラインにするのに数時間 (数日?) かかる可能性があります。
ALTER TABLE [GiantFactTable]
WITH CHECK CHECK CONSTRAINT [FK_GiantFactTable_NewDimValue]
ワークロードについて: テーブルには数百のパーティション (固定数) があり、データは一度に 1 つのパーティションに (ラウンドロビン方式で) 追加され、削除されることはありません。また、クラスタリング キーを使用して、一度に 1 つのパーティションから (比較的小さい) 範囲の行を取得する一定の読み取りワークロードもあります。一度に 1 つのパーティションをチェックしてオフラインにすることは許容されます。しかし、これを行うための構文が見つかりません。他のアイデアはありますか?