# 機能設計書 53-Set-DbaDbCompression

## 概要

本ドキュメントは、SQL Serverデータベースのテーブルとインデックスにデータ圧縮を適用する機能「Set-DbaDbCompression」の設計仕様を記述する。

### 本機能の処理概要

Set-DbaDbCompressionは、SQL Serverデータベースのテーブル、インデックス、ヒープに対してRow圧縮、Page圧縮、または推奨圧縮を適用し、ストレージ容量の削減とI/Oパフォーマンスの向上を実現する機能である。

**業務上の目的・背景**：データベースの成長に伴いストレージコストとバックアップ時間が増加する。データ圧縮は、ディスク使用量を30-70%削減し、バックアップサイズを縮小し、I/O負荷を軽減する効果がある。本機能は、Microsoftタイガーチームの圧縮分析ロジックに基づき、各オブジェクトに最適な圧縮タイプを自動適用することで、手動での分析・適用作業を大幅に削減する。

**機能の利用シーン**：
- 新規データベース構築時の初期圧縮設定
- 既存データベースのストレージ最適化プロジェクト
- 定期メンテナンスでの圧縮状態の統一
- Test-DbaDbCompressionの推奨結果の一括適用

**主要な処理内容**：
1. 対象インスタンス・データベース・テーブルの特定
2. 圧縮タイプに応じた処理分岐（Recommended/Page/Row/None）
3. Recommended時はTest-DbaDbCompressionで分析実行
4. オンラインリビルド可否の判定
5. ヒープ/クラスタ化インデックス/非クラスタ化インデックスへの圧縮適用
6. ビューのインデックスへの圧縮適用

**関連システム・外部連携**：
- Test-DbaDbCompression: 圧縮推奨分析（Recommendedモード時に内部呼び出し）
- SMO: テーブル/インデックスのRebuildメソッド

**権限による制御**：
- データベースのALTER権限が必要
- Enterprise Edition（SQL 2016 SP1以前）またはStandard Edition（SQL 2016 SP1以降）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIコマンド | 主画面 | PowerShellコマンドラインからの直接実行 |

## 機能種別

データ更新 / 構成変更

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス | パイプライン入力可能 |
| SqlCredential | PSCredential | No | SQL Server接続用認証情報 | - |
| Database | string[] | No | 対象データベース名 | ワイルドカード対応 |
| ExcludeDatabase | string[] | No | 除外データベース名 | ワイルドカード対応 |
| Table | string[] | No | 対象テーブル名 | - |
| CompressionType | string | No | 圧縮タイプ（デフォルト: Recommended） | Recommended/Page/Row/None |
| MaxRunTime | int | No | 最大実行時間（分、デフォルト: 0=無制限） | 0以上の整数 |
| PercentCompression | int | No | 最小圧縮率閾値（デフォルト: 0） | 0-100 |
| ForceOfflineRebuilds | switch | No | オフラインリビルドを強制 | - |
| InputObject | object | No | Test-DbaDbCompressionからの推奨オブジェクト | - |
| EnableException | switch | No | 例外をスローする | - |

### 入力データソース

- SqlInstance: パラメータ指定またはパイプライン入力
- InputObject: Test-DbaDbCompressionの出力オブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Database | string | データベース名 |
| Schema | string | スキーマ名 |
| TableName | string | テーブル名 |
| IndexName | string | インデックス名（ヒープの場合はnull） |
| Partition | int | パーティション番号 |
| IndexID | int | インデックスID |
| IndexType | string | インデックスタイプ |
| CompressionTypeRecommendation | string | 適用された圧縮タイプ（ROW/PAGE/NONE） |
| AlreadyProcessed | string | 処理完了フラグ（True/False） |
| PercentScan | int | スキャン操作割合（Recommendedモード時） |
| PercentUpdate | int | 更新操作割合（Recommendedモード時） |
| RowEstimatePercentOriginal | int | Row圧縮時の推定サイズ比率 |
| PageEstimatePercentOriginal | int | Page圧縮時の推定サイズ比率 |
| SizeCurrent | dbasize | 現在のサイズ |
| SizeRequested | dbasize | 圧縮後の推定サイズ |
| PercentCompression | decimal | 圧縮率 |

### 出力先

PowerShellパイプライン（即座に出力）

## 処理フロー

### 処理シーケンス

```
1. SQL Serverインスタンスに接続
   └─ Connect-DbaInstance -MinimumVersion 10

2. エディションチェック
   └─ Enterprise Edition以外はSQL 2016 SP1以降が必要

3. データベース一覧取得・フィルタ
   └─ Database/ExcludeDatabaseパラメータ適用

4. 各データベースの検証
   └─ Status = Normal, CompatibilityLevel >= Version100

5. オンラインリビルドサポート判定
   └─ メモリ最適化/スパースカラム/Columnstoreを除外して判定

6. CompressionTypeによる分岐
   └─ Recommended: Test-DbaDbCompressionで分析 → 適用
   └─ Page/Row/None: 指定タイプを直接適用

7. 各オブジェクトへの圧縮適用
   └─ ヒープ/クラスタ化インデックス: Table.Rebuild()
   └─ 非クラスタ化インデックス: Index.Rebuild()

8. MaxRunTimeチェック
   └─ 経過時間が上限に達したら処理終了

9. 結果出力
   └─ PSCustomObjectとして即座にパイプラインへ出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Connect-DbaInstance]
    B --> C{接続成功?}
    C -->|No| D[Stop-Function]
    D --> A
    C -->|Yes| E{Enterprise Edition?}
    E -->|No| F{SQL 2016 SP1+?}
    F -->|No| G[エラー: エディション不適合]
    F -->|Yes| H[データベースフィルタ]
    E -->|Yes| H
    H --> I[データベースループ]
    I --> J{Status = Normal?}
    J -->|No| K[スキップ]
    K --> I
    J -->|Yes| L{CompatLevel >= 100?}
    L -->|No| K
    L -->|Yes| M[オンラインリビルド判定]
    M --> N{CompressionType?}
    N -->|Recommended| O[Test-DbaDbCompression実行]
    O --> P[推奨結果でループ]
    N -->|Page/Row/None| Q[テーブルループ]
    P --> R{MaxRunTime超過?}
    Q --> R
    R -->|Yes| S[処理終了]
    R -->|No| T[圧縮適用]
    T --> U[結果出力]
    U --> V{次のオブジェクト?}
    V -->|Yes| R
    V -->|No| W{次のDB?}
    W -->|Yes| I
    W -->|No| X[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | エディション制限 | SQL 2016 SP1未満はEnterprise Editionのみ | 常時 |
| BR-02 | 互換性レベル制限 | CompatibilityLevel >= Version100が必要 | 常時 |
| BR-03 | メモリ最適化除外 | IsMemoryOptimized = true のテーブルは除外 | 常時 |
| BR-04 | スパースカラム除外 | HasSparseColumn = true のテーブルは除外 | 常時 |
| BR-05 | Columnstore除外 | Columnstoreインデックスは圧縮対象外 | 常時 |
| BR-06 | NO_GAIN除外 | CompressionTypeRecommendation = NO_GAIN は処理しない | Recommendedモード |
| BR-07 | 圧縮率閾値 | PercentCompression >= パラメータ値のみ処理 | Recommendedモード |

### 計算ロジック

- MaxRunTime判定: (現在時刻 - 開始時刻).TotalMinutes >= MaxRunTime で終了
- PercentCompression: Test-DbaDbCompressionから取得

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 圧縮適用 | ユーザーテーブル | ALTER/REBUILD | DataCompression変更後Rebuild |
| インデックス圧縮 | ユーザーインデックス | ALTER INDEX | OnlineIndexOperation設定後Rebuild |

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

#### ユーザーテーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | PhysicalPartitions.DataCompression | CompressionType値 | SMO経由 |
| REBUILD | - | OnlineHeapOperation設定 | オンライン可否判定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Serverに接続できない | Stop-Functionで処理継続 |
| EditionError | エディションエラー | 非Enterprise + SQL 2016 SP1未満 | Stop-Functionでスキップ |
| CompressionError | 圧縮エラー | Rebuild失敗 | Stop-Functionで処理継続 |

### リトライ仕様

特になし。各オブジェクトは独立して処理され、失敗時は次へ継続する。

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

各Rebuildはオンライン/オフラインでSQL Serverのインデックス再構築トランザクションとして実行される。

## パフォーマンス要件

- オンラインリビルドを優先使用（ForceOfflineRebuilds未指定時）
- MaxRunTimeパラメータでメンテナンスウィンドウ内に収める
- PercentCompressionパラメータで効果の高いオブジェクトのみ処理

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

- SqlCredentialによる認証情報の安全な受け渡し
- ShouldProcess/Confirmによる変更操作の確認

## 備考

- SMOにはNone圧縮設定のバグがあり、その場合はT-SQL直接実行にフォールバック
- Azure SQL Databaseはオンラインリビルドをサポート

---

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

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

### 推奨読解順序

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

出力されるPSCustomObjectの構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Set-DbaDbCompression.ps1 | `public/Set-DbaDbCompression.ps1` | 278-298行目（Page/Row/None時の出力） |
| 1-2 | Set-DbaDbCompression.ps1 | `public/Set-DbaDbCompression.ps1` | 225行目（Recommended時のAlreadyProcessed追加） |

**読解のコツ**: CompressionType=Recommendedの場合とPage/Row/Noneの場合で出力構造が若干異なる。Recommended時はTest-DbaDbCompressionの結果にAlreadyProcessedを追加。

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

パラメータ定義とエディションチェックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaDbCompression.ps1 | `public/Set-DbaDbCompression.ps1` | 139-155行目（パラメータ定義） |
| 2-2 | Set-DbaDbCompression.ps1 | `public/Set-DbaDbCompression.ps1` | 167-169行目（エディションチェック） |

**主要処理フロー**:
1. **161-165行目**: Connect-DbaInstance -MinimumVersion 10
2. **167-169行目**: Enterprise Edition以外はSQL 2016 SP1以降チェック
3. **171-177行目**: データベースフィルタリング

#### Step 3: オンラインリビルド判定を理解する

IsOnlineRebuildSupported判定ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaDbCompression.ps1 | `public/Set-DbaDbCompression.ps1` | 188-208行目 |

**主要処理フロー**:
- **191行目**: メモリ最適化/スパースカラムテーブルを除外してループ
- **195-199行目**: IsOnlineRebuildSupportedまたはAzureでオンライン可と判定

#### Step 4: Recommendedモード処理を理解する

Test-DbaDbCompression呼び出しと結果適用を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Set-DbaDbCompression.ps1 | `public/Set-DbaDbCompression.ps1` | 210-256行目 |

**主要処理フロー**:
- **217行目**: Test-DbaDbCompression実行
- **226行目**: NO_GAIN/'?'を除外、PercentCompression閾値フィルタ
- **231-240行目**: ヒープ/クラスタ化インデックスへの圧縮適用
- **241-252行目**: 非クラスタ化インデックスへの圧縮適用

#### Step 5: Page/Row/Noneモード処理を理解する

直接圧縮適用処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Set-DbaDbCompression.ps1 | `public/Set-DbaDbCompression.ps1` | 257-397行目 |

**主要処理フロー**:
- **264行目**: メモリ最適化/スパースカラム除外
- **269-299行目**: テーブル/ヒープへの圧縮適用
- **301-350行目**: インデックスへの圧縮適用
- **309-318行目**: None圧縮時のSMOバグ回避（T-SQL直接実行）

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

```
Set-DbaDbCompression
    │
    ├─ Connect-DbaInstance (SQL Server接続)
    │
    ├─ [CompressionType = Recommended]
    │      │
    │      ├─ Test-DbaDbCompression (圧縮分析)
    │      │
    │      └─ [foreach: 推奨オブジェクト]
    │             │
    │             ├─ Table.PhysicalPartitions.DataCompression = 推奨値
    │             ├─ Table.Rebuild() (ヒープ/クラスタ化)
    │             │
    │             └─ Index.PhysicalPartitions.DataCompression = 推奨値
    │                 └─ Index.Rebuild() (非クラスタ化)
    │
    └─ [CompressionType = Page/Row/None]
           │
           └─ [foreach: テーブル]
                  │
                  ├─ Table.PhysicalPartitions.DataCompression = 指定値
                  ├─ Table.Rebuild()
                  │
                  └─ [foreach: インデックス]
                         │
                         └─ Index.PhysicalPartitions.DataCompression = 指定値
                             └─ Index.Rebuild()
```

### データフロー図

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

SqlInstance ─────────────▶ Connect-DbaInstance
                                   │
                                   ▼
Database/Table ───────────▶ フィルタリング
                                   │
                                   ▼
CompressionType ──────────▶ ┌─────────────────┐
                           │ Recommended?    │
                           └────────┬────────┘
                                    │
              ┌─────────────────────┼─────────────────────┐
              ▼                     ▼                     ▼
    Test-DbaDbCompression     Page適用              Row/None適用
              │                     │                     │
              └─────────────────────┴─────────────────────┘
                                    │
                                    ▼
                           Table/Index.Rebuild()
                                    │
                                    ▼
                           PSCustomObject ────────────────▶ パイプライン
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaDbCompression.ps1 | `public/Set-DbaDbCompression.ps1` | ソース | メイン機能実装 |
| Test-DbaDbCompression.ps1 | `public/Test-DbaDbCompression.ps1` | ソース | 圧縮推奨分析（内部呼び出し） |
| Get-DbaDbCompression.ps1 | `public/Get-DbaDbCompression.ps1` | ソース | 関連機能（圧縮状態取得） |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
