# 機能設計書 669-Find-DbaSimilarTable

## 概要

本ドキュメントは、データベース間で列名を比較して類似した構造を持つテーブルとビューを検索するFind-DbaSimilarTable機能の設計仕様を記述したものである。

### 本機能の処理概要

Find-DbaSimilarTableは、INFORMATION_SCHEMAビューを使用してデータベース間のテーブルおよびビュー構造を分析し、共有する列名に基づいて構造がどの程度類似しているかを示す一致率を返す機能である。

**業務上の目的・背景**：本番環境の構造を反映するアーカイブテーブルの検出、データベース間で類似の目的を果たす可能性のあるテーブルの特定、またはSQL Server環境全体で特定のテーブルパターンがどこで使用されているかの発見に最適である。すべてのデータベースを検索するか、特定のデータベース、スキーマ、またはテーブルをターゲットにすることができる。一致率を計算するため、最小しきい値を設定して結果をフィルタリングし、最も関連性の高い一致に焦点を当てることができる。

**機能の利用シーン**：
- アーカイブテーブルと本番テーブルの関係性調査
- データベースリファクタリング時の類似テーブル検出
- テーブル命名規則の一貫性監査
- マイグレーション前の影響調査
- データ統合プロジェクトでの重複テーブル検出

**主要な処理内容**：
1. SQLクエリの動的構築（フィルタ条件含む）
2. INFORMATION_SCHEMA.COLUMNSを使用した列名比較
3. 一致率（MatchPercent）の計算
4. しきい値によるフィルタリング
5. 結果オブジェクトの生成と出力

**関連システム・外部連携**：T-SQLクエリをSQL Serverで直接実行し、INFORMATION_SCHEMA.COLUMNSとINFORMATION_SCHEMA.TABLESを結合して比較を行う。

**権限による制御**：対象データベースへのSELECT権限が必要（INFORMATION_SCHEMAビューへのアクセス）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | PowerShellコンソール | 主画面 | コマンド実行と結果表示 |

## 機能種別

データ分析 / 構造比較

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス | パイプライン入力可能 |
| SqlCredential | PSCredential | No | 代替認証情報 | Windows/SQL/AD認証対応 |
| Database | object[] | No | 検索対象データベース | 複数指定可能 |
| ExcludeDatabase | object[] | No | 除外するデータベース | 複数指定可能 |
| SchemaName | string | No | 参照テーブルのスキーマ | - |
| TableName | string | No | 参照テーブル名 | - |
| ExcludeViews | switch | No | ビューを除外 | - |
| IncludeSystemDatabases | switch | No | システムDBを含める | - |
| MatchPercentThreshold | int | No | 最小一致率しきい値 | 0-100 |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- SqlInstance: パイプラインまたはパラメータから取得（必須）
- Database/ExcludeDatabase: フィルタリング条件
- SchemaName/TableName: 比較元テーブルの指定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverのコンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全修飾インスタンス名 |
| Table | string | ソーステーブル完全名 |
| MatchingTable | string | 一致テーブル完全名 |
| MatchPercent | int | 一致率（0-100） |
| OriginalDatabaseName | string | ソースデータベース名 |
| OriginalDatabaseId | int | ソースデータベースID |
| OriginalSchemaName | string | ソーススキーマ名 |
| OriginalTableName | string | ソーステーブル名 |
| OriginalTableNameRankInDB | int | DB内でのテーブルランク |
| OriginalTableType | string | ソースタイプ（TABLE/VIEW） |
| OriginalColumnCount | int | ソース列数 |
| MatchingDatabaseName | string | 一致データベース名 |
| MatchingDatabaseId | int | 一致データベースID |
| MatchingSchemaName | string | 一致スキーマ名 |
| MatchingTableName | string | 一致テーブル名 |
| MatchingTableType | string | 一致タイプ（TABLE/VIEW） |
| MatchingColumnCount | int | 一致テーブル列数 |

### 出力先

パイプライン出力（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. beginブロック：SQLクエリの動的構築
   └─ WHERE/HAVING句の条件追加
2. 各インスタンスへの接続
   └─ MinimumVersion 9（SQL Server 2005以上）
3. データベースリストの取得
   └─ IncludeSystemDatabases/Database/ExcludeDatabase考慮
4. 各データベースでクエリ実行
   └─ $db.Query($sql)
5. 結果のPSCustomObject変換
   └─ 各行を出力オブジェクトに変換
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SQLクエリ構築]
    B --> C{ExcludeViews?}
    C -->|Yes| D[VIEW除外条件追加]
    C -->|No| E{SchemaName?}
    D --> E
    E -->|Yes| F[スキーマ条件追加]
    E -->|No| G{TableName?}
    F --> G
    G -->|Yes| H[テーブル名条件追加]
    G -->|No| I[HAVING句にしきい値設定]
    H --> I
    I --> J[各インスタンスループ]
    J --> K[Connect-DbaInstance]
    K --> L{接続成功?}
    L -->|No| M[Stop-Function -Continue]
    L -->|Yes| N[データベースリスト取得]
    M --> O{次のインスタンス?}
    N --> P[各DBループ]
    P --> Q[クエリ実行]
    Q --> R[結果をPSCustomObjectに変換]
    R --> S[パイプライン出力]
    S --> T{次のDB?}
    T -->|Yes| P
    T -->|No| O
    O -->|Yes| J
    O -->|No| U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-669-1 | 最小バージョン | SQL Server 2005以上が必要 | 常時 |
| BR-669-2 | 自己比較除外 | 同一テーブル同士の比較は除外 | 常時 |
| BR-669-3 | ゼロ一致除外 | 一致率0%は結果から除外 | 常時 |
| BR-669-4 | しきい値フィルタ | MatchPercentThreshold以上のみ出力 | 指定時 |
| BR-669-5 | システムDB除外 | デフォルトでシステムDBは除外 | IncludeSystemDatabases未指定時 |

### 計算ロジック

**一致率計算**:
```sql
100 * COUNT(c2.COLUMN_NAME) / MIN(ColCountsByTable.Column_Count) AS MatchPercent
```
- 分子: 両テーブルで共通する列名の数
- 分母: ソーステーブルの総列数
- 結果: 0-100のパーセンテージ

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 読取 | INFORMATION_SCHEMA.COLUMNS | SELECT | 列情報取得 |
| 読取 | INFORMATION_SCHEMA.TABLES | SELECT | テーブル情報取得 |
| 読取 | sys.databases | SELECT | データベースID取得 |

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

#### INFORMATION_SCHEMA (T-SQL)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, COLUMN_NAME | 全テーブル/ビュー | 自己結合で比較 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Stop-Continue | インスタンス接続失敗 | 次インスタンスへ継続 |
| - | Skip | SQL Server 2005未満 | MinimumVersion 9で自動スキップ |

### リトライ仕様

リトライ処理は実装されていない。

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

読み取り専用操作のためトランザクション管理は不要。

## パフォーマンス要件

- INFORMATION_SCHEMAへのクエリはメタデータ操作で比較的軽量
- 大量のテーブル/ビューを持つデータベースでは実行時間が長くなる可能性
- 複数データベースを順次処理するため、DB数に比例した処理時間

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

- SqlCredentialパラメータで認証情報を安全に受け渡し
- INFORMATION_SCHEMAへのアクセス権限が必要
- シングルクォートのエスケープ処理あり（SQLインジェクション対策）

## 備考

- SQL Server 2005以上が必要（VersionMajor >= 9）
- 参照: https://sqljana.wordpress.com/2017/03/31/sql-server-find-tables-with-similar-table-structure/
- IsAccessibleチェックにより、可用性グループのセカンダリレプリカやミラーリングレプリカのエラー回避

---

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

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

### 推奨読解順序

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

出力されるPSCustomObjectの構造と、SQLクエリの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Find-DbaSimilarTable.ps1 | `public/Find-DbaSimilarTable.ps1` | SQLクエリの構造 |

**読解のコツ**: 141-207行目のSQLクエリ構築部分を先に理解する。CTE（ColCountsByTable）で各テーブルの列数を計算し、自己結合で列名を比較している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Find-DbaSimilarTable.ps1 | `public/Find-DbaSimilarTable.ps1` | メイン処理の流れを把握 |

**主要処理フロー**:
1. **138-247行目**: beginブロック - SQLクエリの動的構築
2. **141-183行目**: SELECT/FROM/JOIN構造の定義
3. **185-207行目**: WHERE/GROUP BY/HAVING/ORDER BY構造
4. **209-243行目**: 条件の動的追加（ExcludeViews, SchemaName, TableName, MatchPercentThreshold）
5. **250-314行目**: processブロック - 各インスタンス・DBの処理
6. **283-304行目**: 結果のPSCustomObject変換

#### Step 3: SQLクエリロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CTE定義 | 同ファイル内 | ColCountsByTableで各テーブルの列数計算 |
| 3-2 | 自己結合 | 同ファイル内 | c.COLUMN_NAME = c2.COLUMN_NAMEで列名比較 |
| 3-3 | 一致率計算 | 同ファイル内 | 100 * COUNT / MINで百分率計算 |

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

```
Find-DbaSimilarTable
    │
    ├─ begin
    │      └─ SQLクエリ動的構築
    │             ├─ $sqlSelect (CTE + SELECT)
    │             ├─ $sqlWhere (WHERE条件)
    │             ├─ $sqlGroupBy (GROUP BY)
    │             ├─ $sqlHaving (HAVING条件)
    │             └─ $sqlOrderBy (ORDER BY)
    │
    └─ process (各インスタンス)
           │
           ├─ Connect-DbaInstance (MinimumVersion 9)
           │
           ├─ データベースリスト取得
           │      ├─ IncludeSystemDatabases
           │      ├─ Database フィルタ
           │      └─ ExcludeDatabase フィルタ
           │
           └─ 各DBループ
                  │
                  ├─ $db.Query($sql)
                  │
                  └─ 各行 → PSCustomObject出力
```

### データフロー図

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

SqlInstance ───────────────▶ Connect-DbaInstance
                                   │
                                   ▼
ExcludeViews ──────────────┐ SQLクエリ構築
SchemaName ────────────────┤     │
TableName ─────────────────┤     │
MatchPercentThreshold ─────┘     │
                                   ▼
Database ──────────────────┐ DBリスト取得
ExcludeDatabase ───────────┤     │
IncludeSystemDatabases ────┘     │
                                   ▼
                            各DBでクエリ実行
                                   │
                                   ▼
                            ┌─────────────────────┐
                            │ INFORMATION_SCHEMA  │
                            │ COLUMNS + TABLES    │
                            │ 自己結合 + 列比較   │
                            └─────────────────────┘
                                   │
                                   ▼
                            PSCustomObject[] ────────▶ パイプライン出力
                            (MatchPercent含む)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Find-DbaSimilarTable.ps1 | `public/Find-DbaSimilarTable.ps1` | ソース | メイン機能実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | 接続確立 |
