# 機能設計書 673-Remove-DbaDbTableData

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける `Remove-DbaDbTableData` コマンドレットの機能設計を記載する。この機能は大量のテーブルデータをバッチ削除し、トランザクションログの肥大化を防ぎながら安全にデータを削除するための機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：大量のデータを単一のDELETE文で削除すると、トランザクションログが急激に増大し、ディスク領域の枯渇やパフォーマンス低下を引き起こす。本機能はAaron Bertrandのチャンク削除技法を実装し、大量削除を管理可能なバッチに分割することで、ログファイルの肥大化やブロッキング問題を防止する。これは履歴データのパージ、監査テーブルのクリーンアップ、データ保持ポリシーの実装、テストデータの削除などに必要不可欠な機能である。

**機能の利用シーン**：
- データ保持ポリシーに基づく古いデータの定期パージ
- データベース移行後の不要データクリーンアップ
- 監査ログテーブルの定期的なアーカイブ・削除
- テスト環境のデータリセット
- Azure SQL Databaseでの大量データ削除（ログ管理自動化対応）

**主要な処理内容**：
1. 削除SQLの構築（TableパラメータまたはカスタムDeleteSql）
2. バッチ単位での削除実行ループ
3. 削除行数のカウントと進捗追跡
4. トランザクションログ管理（Simpleモード: CHECKPOINT、Full/Bulk-logged: ログバックアップ）
5. 詳細なメトリクス情報の出力

**関連システム・外部連携**：
- SQL Server Management Objects (SMO)経由でSQL Serverと通信
- Azure Blob Storage（AzureBaseUrl指定時のログバックアップ先）
- Backup-DbaDatabase（ログバックアップ実行）

**権限による制御**：対象テーブルへのDELETE権限、ログバックアップ実行にはdb_backupoperator権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コマンドライン | 主画面 | PowerShellコンソールまたはスクリプトから実行 |

## 機能種別

CRUD操作（Delete）/ バッチ処理 / データパージ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | No | 接続先SQL Serverインスタンス | 有効なインスタンス名 |
| SqlCredential | PSCredential | No | 代替認証情報 | 有効な資格情報 |
| Database | String[] | No | 対象データベース | 存在するデータベース名 |
| BatchSize | Int | No | バッチ削除行数（デフォルト: 100,000） | 1-1,000,000,000 |
| Table | String | No | 削除対象テーブル名 | 完全修飾名（例: dbo.TableName） |
| DeleteSql | String | No | カスタムDELETE文 | TOP(N)句必須、DELETE句必須 |
| LogBackupPath | String | No | ログバックアップ保存先パス | SQL Server書き込み可能なパス |
| LogBackupTimeStampFormat | String | No | ログバックアップファイル名タイムスタンプ形式 | 有効なGet-Date書式 |
| AzureBaseUrl | String[] | No | Azureストレージコンテナ URL | 有効なAzure Blob URL |
| AzureCredential | String | No | Azure認証資格情報名 | SQL Server Credential名 |
| InputObject | Object[] | No | パイプライン入力 | Database/Server/DbaInstanceParameter |
| EnableException | Switch | No | 例外有効化 | - |

### 入力データソース

- PowerShellコマンドラインパラメータ
- パイプライン入力（Get-DbaDatabase、Connect-DbaInstance経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | String | SQL Serverコンピュータ名 |
| InstanceName | String | インスタンス名 |
| Database | String | データベース名 |
| Sql | String | 実行されたDELETE文 |
| TotalRowsDeleted | Int | 総削除行数 |
| TotalTimeMillis | Double | 総実行時間（ミリ秒） |
| AvgTimeMillis | Double | 平均バッチ実行時間（ミリ秒） |
| TotalIterations | Int | バッチ反復回数 |
| Timings | TimeSpan[] | 各バッチの実行時間配列（非表示） |
| LogBackups | Object[] | ログバックアップ結果配列（非表示） |

### 出力先

- PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. パラメータバリデーション
   └─ Table/DeleteSqlの排他チェック
   └─ BatchSize/DeleteSqlの排他チェック
   └─ LogBackupPath/AzureBaseUrlの排他チェック
   └─ DeleteSqlのTOP/DELETE句チェック
2. DELETE SQL構築
   └─ DEADLOCK_PRIORITY LOW, NOCOUNT ON, XACT_ABORT ON設定
   └─ Table指定: DELETE TOP(BatchSize) FROM Table
   └─ DeleteSql指定: カスタムSQL使用
3. データベース取得
   └─ InputObjectタイプに応じた処理分岐
4. 各データベースに対してループ処理
   └─ ログシッピング/ミラーリング/AG参加の警告表示
   └─ ShouldProcess確認
5. 削除ループ（do-while RowCount > 0）
   └─ DELETE実行・行数取得
   └─ メトリクス収集
   └─ ログ管理（Azure以外）
       └─ Simple: CHECKPOINT
       └─ Full/Bulk: ログバックアップ
6. 結果オブジェクト出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{パラメータバリデーション}
    B -->|エラー| C[終了]
    B -->|OK| D[DELETE SQL構築]
    D --> E[データベース取得]
    E --> F[各DBループ開始]
    F --> G{ログシッピング等確認}
    G --> H[警告表示（該当時）]
    H --> I{ShouldProcess確認}
    I -->|No| F
    I -->|Yes| J[削除ループ開始]
    J --> K[DELETE実行]
    K --> L{エラー発生?}
    L -->|Yes| C
    L -->|No| M[メトリクス収集]
    M --> N{Azure SQL?}
    N -->|Yes| O[ログ管理スキップ]
    N -->|No| P{Recovery Model?}
    P -->|Simple| Q[CHECKPOINT]
    P -->|Full/Bulk| R[ログバックアップ]
    Q --> S{RowCount > 0?}
    R --> S
    O --> S
    S -->|Yes| J
    S -->|No| T[結果オブジェクト出力]
    T --> F
    F -->|完了| U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | Table/DeleteSql排他 | TableとDeleteSqlは同時指定不可 | パラメータ指定時 |
| BR-002 | BatchSize/DeleteSql排他 | DeleteSql使用時はBatchSize指定不可 | パラメータ指定時 |
| BR-003 | DeleteSqlにTOP必須 | DeleteSqlにはTOP(N)句が必須 | DeleteSql指定時 |
| BR-004 | HA環境警告 | ログシッピング/ミラーリング/AG参加時は警告 | 該当構成検出時 |
| BR-005 | Azure自動ログ管理 | Azure SQL Databaseではログ管理処理をスキップ | DatabaseEngineType判定 |

### 計算ロジック

**平均実行時間計算**:
```
AvgTimeMillis = TotalTimeMillis / max(TotalIterations, 1)
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| データ削除 | 指定テーブル | DELETE | バッチ単位での行削除 |
| チェックポイント | トランザクションログ | CHECKPOINT | Simpleモード時のログ解放 |
| ログバックアップ | トランザクションログ | BACKUP LOG | Full/Bulkモード時のログバックアップ |

### テーブル別操作詳細

#### 指定テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE TOP(N) | 全カラム | 指定条件またはテーブル全体 | バッチ単位実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パラメータエラー | Table/DeleteSql両方指定 | いずれか一方のみ指定 |
| - | パラメータエラー | DeleteSqlにTOPなし | TOP(N)句を追加 |
| - | 接続エラー | SQL Server接続不可 | 接続情報確認 |
| - | パスエラー | LogBackupPathアクセス不可 | サービスアカウント権限確認 |
| 40552 | Azure制限エラー | トランザクションログ領域超過 | BatchSize削減 |

### リトライ仕様

削除ループ内でエラー発生時は処理中断。リトライ機能は実装されていない。

## トランザクション仕様

各バッチ削除は個別トランザクションで実行。エラー発生時は該当バッチのみロールバック（XACT_ABORT ON設定）。

```sql
SET DEADLOCK_PRIORITY LOW;
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRANSACTION;
-- DELETE実行
COMMIT TRANSACTION;
-- または ROLLBACK TRANSACTION（エラー時）
```

## パフォーマンス要件

- BatchSizeのデフォルト: 100,000行
- 推奨BatchSize: インデックス多数のテーブルは10,000-50,000行
- Azure SQL: 大きなBatchSizeはエラー40552のリスクあり

## セキュリティ考慮事項

- SqlCredentialパラメータで資格情報を安全に渡すことが可能
- AzureCredentialはSQL Server Credential経由でAzure認証
- ConfirmImpact=Highにより誤操作防止

## 備考

- 参考資料: https://sqlperformance.com/2013/03/io-subsystem/chunk-deletes (Aaron Bertrand)
- 外部キー制約は無効化されないため、依存テーブルから先に削除が必要

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

出力オブジェクトと生成されるSQL構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Remove-DbaDbTableData.ps1 | `public/Remove-DbaDbTableData.ps1` | 379-391行目: 出力オブジェクト構造 |
| 1-2 | Remove-DbaDbTableData.ps1 | `public/Remove-DbaDbTableData.ps1` | 205-241行目: 生成されるSQL構造 |

**読解のコツ**: SQLテンプレートにはDEADLOCK_PRIORITY LOW、NOCOUNT ON、XACT_ABORT ONが設定される。

#### Step 2: エントリーポイントを理解する

begin{}ブロックでのバリデーションとSQL構築を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Remove-DbaDbTableData.ps1 | `public/Remove-DbaDbTableData.ps1` | 166-242行目: begin{}ブロック |

**主要処理フロー**:
1. **167-197行目**: パラメータバリデーション（Table/DeleteSql排他等）
2. **199-202行目**: LogBackupTimeStampFormatデフォルト設定
3. **205-241行目**: DELETE SQL構築

#### Step 3: 削除ループを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Remove-DbaDbTableData.ps1 | `public/Remove-DbaDbTableData.ps1` | 316-377行目: 削除do-whileループ |

**主要処理フロー**:
- **320-322行目**: Measure-CommandでDELETE実行
- **325-327行目**: エラーチェック
- **331-337行目**: メトリクス収集
- **348-371行目**: ログ管理（Azure判定、Recovery Model分岐）
- **377行目**: RowCount > 0 でループ継続

### プログラム呼び出し階層図

```
Remove-DbaDbTableData
    │
    ├─ [begin] バリデーション・SQL構築
    │
    ├─ [process] データベース取得
    │      ├─ Get-DbaDatabase (DbaInstanceParameter/Server)
    │      └─ パイプライン入力 (Database)
    │
    └─ [削除ループ]
           ├─ $db.Query($sql) - DELETE実行
           │
           ├─ [Simple Recovery]
           │      └─ $db.Query("CHECKPOINT")
           │
           └─ [Full/Bulk Recovery]
                  └─ Backup-DbaDatabase -Type Log
```

### データフロー図

```
[入力]                           [処理]                              [出力]

Table/DeleteSql ────────────▶ SQL構築 ──────────────────▶ $sql
BatchSize ──────────────────┘

SqlInstance/InputObject ────▶ DB取得 ──────────────────▶ $dbDatabases[]

                                         │
                                         ▼
                              ┌─────── 削除ループ ───────┐
                              │                          │
                              │  DELETE実行              │
                              │      │                   │
                              │      ▼                   │
                              │  メトリクス収集          │
                              │      │                   │
                              │      ▼                   │
                              │  ログ管理               │
                              │      │                   │
                              │      ▼                   │
                              │  RowCount > 0 ? ────────┘
                              │
                              ▼
                       PSCustomObject
                              │
                              ▼
                    TotalRowsDeleted, Timings, etc.
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Remove-DbaDbTableData.ps1 | `public/Remove-DbaDbTableData.ps1` | ソース | メイン機能実装 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得 |
| Backup-DbaDatabase.ps1 | `public/Backup-DbaDatabase.ps1` | ソース | ログバックアップ |
| Test-DbaPath.ps1 | `public/Test-DbaPath.ps1` | ソース | パスアクセス確認 |
| Remove-DbaDbTableData.Tests.ps1 | `tests/Remove-DbaDbTableData.Tests.ps1` | テスト | 単体テスト |
