次のシナリオの SQL Server 2012 データベースのソリューションを設計しています。
- データベースには、4 つまたは 5 つのテーブル間のいくつかの単純な親子関係を持つ約 1M のレコードが含まれています
- データベースには 24 時間 365 日、高負荷の読み取りがあります
- 1 日に 1 回、データベースにマージする必要がある約 1000 の挿入、更新、および削除を含むバッチを受け取りますが、この数はさらに多くなる場合があります。
- 毎日のバッチとは別に、データベースへの他のライターはありません
いくつかの「特別な」要件があります
- これらの更新により、リーダーが大幅な遅延を経験することはありません。
- リーダーの観点から、バッチ全体をアトミックに処理する必要があります。部分的に処理されたバッチがリーダーに表示されないようにする必要があります
- 更新が途中で失敗した場合は、バッチのすべての変更をロールバックする必要があります
- バッチ自体の処理はタイム クリティカルではありません。単純な実装では数分程度で十分です。
私が考えている選択肢は
単一のデータベース トランザクションを更新バッチ全体にラップし (これは大規模なトランザクションになる可能性があります)、スナップショット分離を使用して、更新の実行中にリーダーが元のデータを読み取れるようにします。
パーティションの切り替えを使用する、このようなユースケースを念頭に置いて設計された機能のようです。欠点は、バッチの処理を開始する前に、すべての元のデータのコピーを作成する必要があることです。
データベース全体を切り替えます。データベース全体のコピーを作成し、このコピーでバッチを処理してから、すべてのクライアントをこのデータベースにリダイレクトできます (接続文字列を変更するなど)。これにより、データベースを読み取り専用にし、場合によってはスケーラビリティのためにデータベースの複数のコピーを作成することもできます。
これらのオプションのうち、このシナリオに最も適しているのはどれですか? また、その理由は何ですか?