Schema Inspector / information_schema 實作前確認
1. 文件目的
本文件整理進入 Schema Inspector / information_schema 前需要確認的範圍、資料來源、讀取欄位、測試方式與停止條件。
此節點的目標不是執行 DDL,也不是啟動自動建表,而是先確認「如何安全讀取 MySQL 既有 schema」,讓後續 Dry Run Plan 可以從真實資料庫現況產生。
2. 目前前置狀態
| 項目 | 狀態 |
|---|---|
| MySQL 版本 | 使用者指定為 MySQL 5.6.2 |
| SQL Generator | 已完成 CREATE TABLE IF NOT EXISTS、ADD COLUMN、ADD INDEX |
| Dry Run Plan | 已完成第一版純程式比對 |
| 目前測試數 | dotnet test 通過 278 個測試 |
| 最新程式 commit | db0b1b8 |
| 真實 MySQL 連線 | 尚未導入 |
| DDL 執行 | 尚未導入 |
| MySQL 套件導入 | 尚未在本節點執行 |
3. 本節點建議目標
第一版 Schema Inspector 建議只做「讀取真實 DB schema 快照」,不做任何修改。
| 目標 | 說明 |
|---|---|
| 讀取 table 清單 | 從 information_schema.TABLES 取得指定 database 的 table |
| 讀取 column 清單 | 從 information_schema.COLUMNS 取得欄位名稱、型別、nullable、預設值、comment |
| 讀取 index 清單 | 從 information_schema.STATISTICS 取得 index 名稱、欄位順序、是否 unique |
| 讀取 primary key | 可由 information_schema.KEY_COLUMN_USAGE 或 STATISTICS 判斷 |
| 轉成 schema snapshot | 轉成專案內部 SchemaDefinition / TableDefinition / ColumnDefinition / IndexDefinition 相容資料 |
| 提供給 Dry Run Plan | 將現有 DB snapshot 與目標 schema 比對 |
4. 明確不做的事
| 不做項目 | 原因 |
|---|---|
不執行 CREATE TABLE | Inspector 只讀,不負責建表 |
不執行 ALTER TABLE | 避免尚未確認前修改資料庫 |
不執行 DROP / MODIFY / CHANGE | 破壞性或高風險 SQL 必須另行確認 |
| 不把密碼寫進文件或 repo | 避免洩漏敏感資訊 |
| 不在 Core 直接依賴 MySQL 套件 | 避免破壞分層,DB 讀取應放在 Infrastructure 或專屬 schema 模組 |
| 不接 ConsoleHost 自動啟動流程 | 啟動自動建表需等 Inspector、Plan、Executor 都確認後再做 |
5. information_schema 查詢範圍
5.1 information_schema.TABLES
建議讀取欄位:
| 欄位 | 用途 |
|---|---|
TABLE_SCHEMA | 限制 database |
TABLE_NAME | 對應 table name |
TABLE_COMMENT | 對應 table description |
ENGINE | 確認是否為 InnoDB 等預期 engine |
TABLE_COLLATION | 後續判斷字元集與排序規則 |
5.2 information_schema.COLUMNS
建議讀取欄位:
| 欄位 | 用途 |
|---|---|
TABLE_NAME | 對應所屬 table |
COLUMN_NAME | 對應 column name |
COLUMN_TYPE | 保留完整 MySQL 型別,例如 varchar(64) |
DATA_TYPE | 判斷基礎型別,例如 varchar、datetime |
CHARACTER_MAXIMUM_LENGTH | 判斷字串長度 |
NUMERIC_PRECISION / NUMERIC_SCALE | 判斷數值精度 |
IS_NULLABLE | 對應 nullable |
COLUMN_DEFAULT | 保留 default 資訊 |
COLUMN_COMMENT | 對應欄位描述 |
ORDINAL_POSITION | 保留欄位順序 |
5.3 information_schema.STATISTICS
建議讀取欄位:
| 欄位 | 用途 |
|---|---|
TABLE_NAME | 對應所屬 table |
INDEX_NAME | 對應 index name |
COLUMN_NAME | 對應 index 欄位 |
NON_UNIQUE | 判斷 unique / non-unique |
SEQ_IN_INDEX | 還原複合 index 欄位順序 |
5.4 information_schema.KEY_COLUMN_USAGE
建議用途:
| 用途 | 說明 |
|---|---|
| 判斷 primary key | 可輔助確認 primary key 欄位 |
| 保留外鍵資訊 | 第一版可先讀取但不進入自動修正 |
第一版可以只把外鍵列為 ManualReviewItems 或 warning,不建議自動產生 foreign key DDL。
6. MySQL 5.6.2 注意事項
| 項目 | 注意事項 |
|---|---|
| JSON 型別 | MySQL 5.6.2 不支援原生 json,仍需映射為 text 或 varchar |
datetime 精度 | 需避免使用較新版本才穩定支援的語法 |
| generated column | 第一版不納入 |
| online DDL | 第一版不依賴 |
| collation | 先讀取與記錄,不在第一版自動修正 |
| foreign key | 先讀取與記錄,不在第一版自動建立或修改 |
7. 建議程式邊界
| 元件 | 建議責任 |
|---|---|
ISchemaInspector | 定義讀取目前 schema snapshot 的抽象介面 |
MySqlSchemaInspector | 透過 MySQL 連線讀取 information_schema |
SchemaDefinition | 表示目標 schema 或目前 DB snapshot |
MySqlSchemaSqlGenerator | 只負責產生 SQL 字串 |
SchemaMigrationPlan | 表示 dry run 比對結果 |
SchemaInitializer | 後續才負責串接 inspector、generator、executor |
建議第一版不要把 MySQL 讀取邏輯放進 Core。Core 可以保留抽象 model 與比對結果,真實 DB 讀取應放在 Infrastructure 或專門的 MySQL schema 實作區。
8. 測試策略
| 測試層級 | 建議方式 |
|---|---|
| 單元測試 | 使用 fake / in-memory reader 模擬 information_schema 查詢結果 |
| mapping 測試 | 確認 table、column、index 可正確轉成 schema snapshot |
| MySQL 5.6.2 相容測試 | 先以文件列出必要查詢語法,實際連線測試需使用者提供測試 DB |
| 安全測試 | 確認 Inspector 不產生 DDL、不呼叫 executor、不修改 DB |
| 異常測試 | 連線失敗、權限不足、database 不存在、查詢結果空集合 |
9. 需要使用者確認的項目
| 項目 | 為什麼需要確認 |
|---|---|
是否允許導入 MySqlConnector | 這會新增核心資料庫連線套件 |
| MySQL 測試 DB 連線資訊 | Inspector 若要做真實連線測試,需要 host、port、dbname、user 與密碼提供方式 |
| 測試帳號權限 | 第一版建議只需要 SELECT information_schema 與目標 database metadata |
| 是否允許新增 Infrastructure 專案或資料夾 | 會影響專案分層與檔案位置 |
| 是否需要先只做 mock inspector | 可避免先接真實 DB,也能完成 mapping 與 Dry Run 串接測試 |
10. 建議決策
我的建議是先採用「兩段式」:
1. 先做 ISchemaInspector 與 mock / fake inspector,驗證 mapping 到 SchemaDefinition 與 Dry Run Plan 串接。 2. 再經使用者確認後導入 MySqlConnector,實作 MySqlSchemaInspector 查詢 information_schema。
這樣可以先把架構與測試補齊,同時避免太早接觸真實資料庫、密碼與外部環境。
11. 建議下一步
建議下一步先做:
Schema Inspector 抽象介面與 mock inspector 實作前確認
此步驟可先不導入 MySQL 套件、不連線 DB,只確認介面、回傳模型、錯誤格式與測試案例。
若要直接進入真實 MySQL Inspector,則需先確認:
- 是否允許新增
MySqlConnector。 - MySQL 測試連線資訊如何提供。
- 測試帳號是否只有讀取權限。
- Inspector 實作放在哪一層。