213 lines
6.2 KiB
Markdown
213 lines
6.2 KiB
Markdown
# 資料庫命名規範統一計劃
|
||
|
||
## 📋 計劃概述
|
||
|
||
本計劃旨在解決 DramaLing 專案中資料庫欄位命名不一致的問題,將所有資料庫欄位統一為 `snake_case` 命名規範。
|
||
|
||
## 🔍 現況分析
|
||
|
||
### 問題描述
|
||
目前資料庫中同時存在兩種命名方式:
|
||
- **PascalCase**: `Example`, `Word`, `Translation`, `Definition`, `Name`, `Color` 等
|
||
- **snake_case**: `user_id`, `created_at`, `is_favorite`, `part_of_speech` 等
|
||
|
||
### 問題根源
|
||
1. **歷史遺留**: 早期遷移沒有統一配置欄位命名
|
||
2. **不完整配置**: 部分屬性缺少 `.HasColumnName()` 映射
|
||
3. **維護疏漏**: 新增欄位時沒有遵循統一規範
|
||
|
||
### 已修復項目 ✅
|
||
- ✅ `Flashcard.Word` → `word`
|
||
- ✅ `Flashcard.Translation` → `translation`
|
||
- ✅ `Flashcard.Definition` → `definition`
|
||
- ✅ `Flashcard.Pronunciation` → `pronunciation`
|
||
- ✅ `Flashcard.Example` → `example` (原始問題)
|
||
|
||
## 🎯 統一規範標準
|
||
|
||
### 命名規則
|
||
| 層級 | 命名方式 | 範例 | 說明 |
|
||
|------|----------|------|------|
|
||
| **C# 實體屬性** | PascalCase | `UserId`, `CreatedAt`, `ExampleTranslation` | 符合 C# 慣例 |
|
||
| **資料庫欄位** | snake_case | `user_id`, `created_at`, `example_translation` | 符合資料庫慣例 |
|
||
| **表格名稱** | snake_case | `flashcards`, `user_profiles`, `daily_stats` | 保持一致性 |
|
||
|
||
### 映射規則
|
||
```csharp
|
||
// 所有屬性都需要明確映射
|
||
entity.Property(e => e.PropertyName).HasColumnName("property_name");
|
||
```
|
||
|
||
## 📝 待修復項目清單
|
||
|
||
### 1. Tag 實體
|
||
```csharp
|
||
// 目前缺少的映射:
|
||
public Guid Id { get; set; } // → "id"
|
||
public string Name { get; set; } // → "name"
|
||
public string Color { get; set; } // → "color"
|
||
```
|
||
|
||
### 2. ErrorReport 實體
|
||
```csharp
|
||
// 目前缺少的映射:
|
||
public Guid Id { get; set; } // → "id"
|
||
public string? Description { get; set; } // → "description"
|
||
public string Status { get; set; } // → "status"
|
||
```
|
||
|
||
### 3. DailyStats 實體
|
||
```csharp
|
||
// 目前缺少的映射:
|
||
public Guid Id { get; set; } // → "id"
|
||
public DateTime Date { get; set; } // → "date"
|
||
```
|
||
|
||
### 4. 其他實體
|
||
需要檢查以下實體是否有遺漏的映射:
|
||
- `SentenceAnalysisCache`
|
||
- `WordQueryUsageStats`
|
||
- `ExampleImage`
|
||
- `ImageGenerationRequest`
|
||
- `OptionsVocabulary`
|
||
|
||
### 5. 通用 Id 欄位
|
||
所有實體的 `Id` 屬性都應該映射為 `id`
|
||
|
||
## 🚀 執行步驟
|
||
|
||
### 階段一:DbContext 配置更新
|
||
1. **補充 Tag 實體配置**
|
||
```csharp
|
||
private void ConfigureTagEntities(ModelBuilder modelBuilder)
|
||
{
|
||
var tagEntity = modelBuilder.Entity<Tag>();
|
||
tagEntity.Property(t => t.Id).HasColumnName("id");
|
||
tagEntity.Property(t => t.Name).HasColumnName("name");
|
||
tagEntity.Property(t => t.Color).HasColumnName("color");
|
||
// 其他現有配置...
|
||
}
|
||
```
|
||
|
||
2. **補充其他實體配置**
|
||
- 更新 `ConfigureErrorReportEntity`
|
||
- 更新 `ConfigureDailyStatsEntity`
|
||
- 新增其他實體的配置方法
|
||
|
||
### 階段二:資料庫遷移
|
||
1. **建立遷移**
|
||
```bash
|
||
dotnet ef migrations add CompleteSnakeCaseNaming
|
||
```
|
||
|
||
2. **套用遷移**
|
||
```bash
|
||
dotnet ef database update
|
||
```
|
||
|
||
### 階段三:驗證與測試
|
||
1. **檢查資料庫結構**
|
||
```sql
|
||
.schema table_name
|
||
```
|
||
|
||
2. **測試應用程式功能**
|
||
- API 端點測試
|
||
- 資料查詢測試
|
||
- 完整功能驗證
|
||
|
||
## 📋 檢核清單
|
||
|
||
### 配置檢核
|
||
- [ ] 所有實體的 `Id` 屬性都有 `.HasColumnName("id")`
|
||
- [ ] 所有多單字屬性都使用 snake_case(如 `CreatedAt` → `created_at`)
|
||
- [ ] 所有布林屬性都使用 `is_` 前綴(如 `IsActive` → `is_active`)
|
||
- [ ] 外鍵屬性都使用 `_id` 後綴(如 `UserId` → `user_id`)
|
||
|
||
### 遷移檢核
|
||
- [ ] 遷移檔案正確生成
|
||
- [ ] SQL 指令正確(RENAME COLUMN)
|
||
- [ ] 沒有資料遺失風險
|
||
- [ ] 回滾計劃準備完成
|
||
|
||
### 測試檢核
|
||
- [ ] 所有 API 端點正常運作
|
||
- [ ] 資料查詢結果正確
|
||
- [ ] 無效能退化
|
||
- [ ] 前端功能正常
|
||
|
||
## 🔧 長期維護建議
|
||
|
||
### 1. 編碼規範
|
||
建立明確的編碼規範文檔:
|
||
```markdown
|
||
## 資料庫命名規範
|
||
- 所有新增的實體屬性都必須配置 `.HasColumnName()`
|
||
- 資料庫欄位名稱統一使用 snake_case
|
||
- 布林欄位使用 `is_` 前綴
|
||
- 外鍵欄位使用 `_id` 後綴
|
||
```
|
||
|
||
### 2. Code Review 檢查點
|
||
在 PR 審查時檢查:
|
||
- 新增實體是否有完整的欄位映射配置
|
||
- 遷移檔案是否符合命名規範
|
||
- 是否需要更新相關文檔
|
||
|
||
### 3. 自動化檢查
|
||
考慮實施:
|
||
- **Pre-commit Hook**: 檢查新增的 DbContext 配置
|
||
- **CI/CD 檢查**: 驗證遷移檔案的正確性
|
||
- **單元測試**: 確保所有實體都有正確的欄位映射
|
||
|
||
### 4. 全局慣例配置(進階選項)
|
||
可以考慮使用 EF Core 的全局慣例:
|
||
```csharp
|
||
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
|
||
{
|
||
configurationBuilder.Properties<string>()
|
||
.HaveColumnName(propertyInfo => propertyInfo.Name.ToSnakeCase());
|
||
}
|
||
```
|
||
|
||
## 📊 影響評估
|
||
|
||
### 優點
|
||
- ✅ 統一的命名規範
|
||
- ✅ 更好的可維護性
|
||
- ✅ 避免開發混淆
|
||
- ✅ 符合業界標準
|
||
|
||
### 風險
|
||
- ⚠️ 需要資料庫遷移
|
||
- ⚠️ 可能影響現有查詢
|
||
- ⚠️ 需要充分測試
|
||
|
||
### 緩解措施
|
||
- 📋 充分的測試計劃
|
||
- 🔄 準備回滾方案
|
||
- 📝 詳細的變更文檔
|
||
- 👥 團隊溝通協調
|
||
|
||
## 🗓️ 執行時間表
|
||
|
||
| 階段 | 預估時間 | 責任人 | 狀態 |
|
||
|------|----------|--------|------|
|
||
| 現況分析 | 0.5 天 | 開發團隊 | ✅ 完成 |
|
||
| 配置更新 | 1 天 | 後端開發 | 🚧 進行中 |
|
||
| 遷移建立 | 0.5 天 | 後端開發 | ⏳ 待執行 |
|
||
| 測試驗證 | 1 天 | 全團隊 | ⏳ 待執行 |
|
||
| 部署上線 | 0.5 天 | DevOps | ⏳ 待執行 |
|
||
|
||
## 📞 聯絡資訊
|
||
|
||
如有問題或需要協助,請聯絡:
|
||
- **技術負責人**: [待填入]
|
||
- **專案經理**: [待填入]
|
||
- **QA 負責人**: [待填入]
|
||
|
||
---
|
||
|
||
**文件版本**: v1.0
|
||
**最後更新**: 2025-09-30
|
||
**建立人**: Claude Code Assistant |