Files
WCTDataMiner/docs/data-model/概览.md

266 lines
8.1 KiB
Markdown
Raw Normal View History

# Data Model: WCTDataMiner
> WCTDataMiner 数据库模型规格,采用维度表设计,消除数据冗余
---
## 文档索引
### 维度表
| 文档 | 说明 |
|------|------|
| [TX面板维度](./entities/TxPanel维度.md) | TX面板类型维度 |
| [TX硬件版本维度](./entities/TxHardware维度.md) | TX硬件版本维度 |
| [TX软件版本维度](./entities/TxSoftware维度.md) | TX软件版本维度 |
| [RX类型维度](./entities/RxType维度.md) | RX类型维度 |
### 事实表
| 文档 | 说明 |
|------|------|
| [测试场景实体](./entities/测试场景.md) | 测试场景(外键组合) |
| [Qfod 记录实体](./entities/Qfod记录.md) | Qfod 检测数据 |
| [Ploss 记录实体](./entities/Ploss记录.md) | Ploss FOD 数据 |
| [关系说明](./关系说明.md) | 实体间关系定义 |
---
## 实体列表
### 维度表4张
| 表名 | 职责 | 关键字段 |
|------|------|----------|
| tx_panel | TX面板类型维度 | name (UNIQUE) |
| tx_hardware | TX硬件版本维度 | version (UNIQUE) |
| tx_software | TX软件版本维度 | version (UNIQUE) |
| rx_type | RX类型维度 | name (UNIQUE) |
### 事实表3张
| 表名 | 职责 | 关键字段 |
|------|------|----------|
| test_scenario | 测试场景组合 | 4个维度外键 + test_purpose + test_date |
| qfod_record | Qfod 检测数据 | scenario_id, delta_q, fod_type |
| ploss_record | Ploss FOD 数据 | scenario_id, ploss, threshold |
---
## ER 关系图
```mermaid
erDiagram
tx_panel ||--o{ test_scenario : "引用"
tx_hardware ||--o{ test_scenario : "引用"
tx_software ||--o{ test_scenario : "引用"
rx_type ||--o{ test_scenario : "引用"
test_scenario ||--o{ qfod_record : "包含"
test_scenario ||--o{ ploss_record : "包含"
tx_panel {
uuid id PK "主键"
varchar name UK "面板类型"
}
tx_hardware {
uuid id PK "主键"
varchar version UK "硬件版本"
}
tx_software {
uuid id PK "主键"
varchar version UK "软件版本"
}
rx_type {
uuid id PK "主键"
varchar name UK "RX类型"
}
test_scenario {
uuid id PK "主键"
uuid tx_panel_id FK "面板外键"
uuid tx_hardware_id FK "硬件外键"
uuid tx_software_id FK "软件外键"
uuid rx_type_id FK "RX外键"
varchar test_purpose "测试目的"
date test_date "测试日期"
int test_sequence "测试序号"
int qfod_count "Qfod记录数"
int ploss_count "Ploss记录数"
}
qfod_record {
uuid id PK "主键"
uuid scenario_id FK "场景外键"
tinyint charger_index "充电器索引"
tinyint coil_index "线圈索引"
int delta_q "Q值变化量"
float current_q "当前Q值"
float raw_q "原始Q值"
tinyint fod_type "异物类型"
}
ploss_record {
uuid id PK "主键"
uuid scenario_id FK "场景外键"
tinyint rx_type "接收端类型"
smallint rx_power "接收端功率"
smallint tx_power "发射端功率"
int ploss "计算损耗值"
int threshold "阈值"
smallint fod_result "FOD判定结果"
}
```
---
## 设计说明
### 星型模型架构
本设计采用星型模型Star Schema
- **维度表**存储可能重复的属性值面板、硬件版本、软件版本、RX类型
- **事实表**:存储外键组合和度量数据
**优势**
- 维度值只存一份,消除冗余
- 维度可复用,相同硬件版本在不同场景中引用同一记录
- 查询可按维度灵活筛选和分组
### test_purpose 处理
`test_purpose` 直接存储在场景表中,不拆分维度表,原因:
- 测试目的描述较自由,不适合标准化为维度
- 便于用户灵活输入
### 场景唯一性
场景表设置唯一约束,相同属性组合不重复创建:
```
UNIQUE(tx_panel_id, tx_hardware_id, tx_software_id, rx_type_id, test_purpose, test_date, test_sequence)
```
### 软删除设计
所有表均包含 `is_deleted` 字段,支持软删除:
| 字段名 | 类型 | 约束 | 说明 |
|--------|------|------|------|
| is_deleted | BOOLEAN | NOT NULL, DEFAULT FALSE | 软删除标记 |
**删除行为**
- 删除操作设置 `is_deleted = true`,不物理删除数据
- 查询时默认过滤已删除记录(`WHERE is_deleted = false`
- 支持数据恢复和审计追溯
**查询示例**
```csharp
// 默认查询(不含已删除)
var activeRecords = context.TxPanels
.Where(t => !t.IsDeleted)
.ToList();
// 包含已删除记录
var allRecords = context.TxPanels
.IgnoreQueryFilters()
.ToList();
// 软删除操作
public async Task SoftDeleteAsync(Guid id)
{
var entity = await context.TxPanels.FindAsync(id);
if (entity != null)
{
entity.IsDeleted = true;
await context.SaveChangesAsync();
}
}
```
### 实体配置方式
采用 `IEntityTypeConfiguration<T>` Fluent API 配置,实体类保持纯净 POCO
```csharp
// Data/WctMinerDbContext.cs
using Microsoft.EntityFrameworkCore;
using WCTDataMiner.Models;
namespace WCTDataMiner.Data;
public class WctMinerDbContext : DbContext
{
public WctMinerDbContext(DbContextOptions<WctMinerDbContext> options)
: base(options) { }
public DbSet<TxPanel> TxPanels => Set<TxPanel>();
public DbSet<TxHardware> TxHardwares => Set<TxHardware>();
public DbSet<TxSoftware> TxSoftwares => Set<TxSoftware>();
public DbSet<RxType> RxTypes => Set<RxType>();
public DbSet<TestScenario> TestScenarios => Set<TestScenario>();
public DbSet<QfodRecord> QfodRecords => Set<QfodRecord>();
public DbSet<PlossRecord> PlossRecords => Set<PlossRecord>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 自动应用所有 IEntityTypeConfiguration<T> 配置
modelBuilder.ApplyConfigurationsFromAssembly(typeof(WctMinerDbContext).Assembly);
}
}
```
> **数据库兼容性说明**
> - `HasDefaultValueSql("NOW()")` 适用于 PostgreSQL
> - 若使用 SQLite需改为 `HasDefaultValueSql("datetime('now')")`
> - 若使用 MySQL需改为 `HasDefaultValueSql("NOW()")`MySQL 也支持)
> - 若使用 SQL Server需改为 `HasDefaultValueSql("GETDATE()")`
**配置类列表**
| 配置类 | 文件路径 | 说明 |
|--------|----------|------|
| TxPanelConfiguration | Data/Configurations/TxPanelConfiguration.cs | TX面板维度 |
| TxHardwareConfiguration | Data/Configurations/TxHardwareConfiguration.cs | TX硬件版本维度 |
| TxSoftwareConfiguration | Data/Configurations/TxSoftwareConfiguration.cs | TX软件版本维度 |
| RxTypeConfiguration | Data/Configurations/RxTypeConfiguration.cs | RX类型维度 |
| TestScenarioConfiguration | Data/Configurations/TestScenarioConfiguration.cs | 测试场景 |
| QfodRecordConfiguration | Data/Configurations/QfodRecordConfiguration.cs | Qfod记录 |
| PlossRecordConfiguration | Data/Configurations/PlossRecordConfiguration.cs | Ploss记录 |
> **迁移注意事项**:从 DataAnnotations `DateTime.UtcNow` 迁移到 `HasDefaultValueSql("NOW()")` 后,测试代码需注意:未显式设置 `CreatedAt` 时,值由数据库生成而非 C# 运行时。单元测试中需 mock 数据库或显式设置值。
### 系统日志处理
解析过程中的错误日志通过 Serilog 记录到系统日志文件,不存入业务数据库。
---
## 数据量估算
| 表 | 增长方式 | 预估规模 |
|------|----------|----------|
| tx_panel | 预置数据 | 7 条(固定枚举) |
| tx_hardware | 随版本迭代 | 10-50 条/年 |
| tx_software | 随版本迭代 | 10-50 条/年 |
| rx_type | 随设备增加 | 20-100 条/年 |
| test_scenario | 随测试批次 | 3,650 条/年 |
| qfod_record | 随测试数据 | 3.6M-18M 条/年 |
| ploss_record | 随测试数据 | 3.6M-18M 条/年 |
---
## 假设/歧义标注
| 标注 | 内容 |
|------|------|
| [A] | 使用 UUID 作为主键 |
| [?] | FOD Type 具体编码含义需确认 |
| [?] | Ploss 日志格式与实际日志对应关系需确认 |
| [!] | ploss 负数表示安全,正数可能触发 FOD |