HaniBlindBox/.kiro/specs/database-migration/design.md
2026-01-02 05:18:05 +08:00

285 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Design Document: Database Migration
## Overview
本设计文档描述了将 HoneyBox 盲盒抽奖系统数据库从 MySQL 5.7 迁移到 SQL Server 2022 的技术方案。迁移涉及 82 个表中的约 30 个核心业务表,数据量约 50MB包括 2,202 个用户、503 个商品和相关订单数据。
### 迁移目标
- 平台升级MySQL 5.7.44 → SQL Server 2022
- 性能提升:查询性能提升 50-80%
- 生态集成:与 .NET 8 完美集成
- 现代化:利用 SQL Server 2022 企业级特性
## Architecture
### 迁移架构图
```mermaid
graph TB
subgraph Source["源数据库 (MySQL 5.7)"]
MySQL[(MySQL 5.7<br/>youdas)]
end
subgraph Migration["迁移层"]
Backup[数据备份]
Transform[数据转换]
Validate[数据验证]
end
subgraph Target["目标数据库 (SQL Server 2022)"]
SQLServer[(SQL Server 2022<br/>honey_box)]
end
subgraph App["应用层"]
API[.NET 8 API]
EFCore[EF Core 8.0]
end
MySQL --> Backup
Backup --> Transform
Transform --> SQLServer
SQLServer --> Validate
Validate --> |验证通过| EFCore
EFCore --> API
```
### 迁移流程
```mermaid
flowchart LR
A[阶段1<br/>业务分析] --> B[阶段2<br/>环境搭建]
B --> C[阶段3<br/>表结构创建]
C --> D[阶段4<br/>数据迁移]
D --> E[阶段5<br/>数据验证]
E --> F[阶段6<br/>应用适配]
```
## Components and Interfaces
### 1. 迁移脚本组件
#### 1.1 表结构创建脚本
- **职责**:在 SQL Server 中创建所有目标表
- **输入**:表结构设计文档
- **输出**SQL Server 表结构
#### 1.2 数据迁移脚本
- **职责**:从 MySQL 导出数据并导入 SQL Server
- **输入**MySQL 源数据
- **输出**SQL Server 目标数据
#### 1.3 数据验证脚本
- **职责**:验证迁移后数据的完整性和一致性
- **输入**:源数据库和目标数据库
- **输出**:验证报告
### 2. 数据转换规则
#### 2.1 数据类型映射
| MySQL 类型 | SQL Server 类型 | 说明 |
|-----------|----------------|------|
| INT | INT | 直接映射 |
| BIGINT | BIGINT | 直接映射 |
| TINYINT | TINYINT | 直接映射 |
| VARCHAR(n) | NVARCHAR(n) | 支持中文 |
| TEXT | NVARCHAR(MAX) | 大文本 |
| DECIMAL(m,n) | DECIMAL(m,n) | 直接映射 |
| INT (时间戳) | DATETIME2 | 需要转换 |
#### 2.2 字段命名转换
- MySQL: `addtime` → SQL Server: `created_at`
- MySQL: `update_time` → SQL Server: `updated_at`
- MySQL: `imgurl` → SQL Server: `img_url`
- 统一使用 snake_case 命名规范
### 3. 核心表结构设计
#### 3.1 用户表 (users)
```sql
CREATE TABLE users (
id INT IDENTITY(1,1) PRIMARY KEY,
open_id NVARCHAR(50) NOT NULL,
union_id NVARCHAR(255) NULL,
mobile NVARCHAR(15) NULL,
nickname NVARCHAR(255) NOT NULL,
head_img NVARCHAR(500) NOT NULL,
money DECIMAL(18,2) NOT NULL DEFAULT 0,
integral DECIMAL(18,2) NOT NULL DEFAULT 0,
status TINYINT NOT NULL DEFAULT 1,
created_at DATETIME2 NOT NULL DEFAULT GETDATE(),
updated_at DATETIME2 NOT NULL DEFAULT GETDATE(),
CONSTRAINT uk_users_open_id UNIQUE (open_id)
);
```
#### 3.2 商品表 (goods)
包含 54 个字段,涵盖:
- 基础信息(标题、图片、价格)
- 库存控制(总库存、已售库存)
- 限购控制(每日限购、全局限购)
- 福利屋功能(开关、时间范围)
- 特殊功能(灵珠、连击、暴怒)
#### 3.3 订单表 (orders)
包含 33 个字段,涵盖:
- 订单基础信息
- 支付方式组合(余额、积分、优惠券)
- 抽奖结果关联
## Data Models
### 实体关系图
```mermaid
erDiagram
users ||--o{ orders : "places"
users ||--o{ user_accounts : "has"
users ||--o{ user_addresses : "has"
users ||--o{ coupon_receives : "receives"
goods ||--o{ orders : "ordered_in"
goods ||--o{ goods_items : "contains"
goods ||--o{ goods_extensions : "has"
orders ||--o{ order_items : "contains"
goods_types ||--o{ goods : "categorizes"
prize_levels ||--o{ goods_items : "defines"
coupons ||--o{ coupon_receives : "issued_as"
diamond_products ||--o{ diamond_orders : "purchased_as"
users ||--o{ diamond_orders : "places"
```
### 核心表清单
| 表名 | 原表名 | 记录数 | 说明 |
|-----|-------|-------|------|
| users | user | 2,201 | 用户主表 |
| user_accounts | user_account | 3,452 | 用户账户 |
| goods | goods | 503 | 商品主表 |
| goods_items | goods_list | 1,844 | 商品奖品 |
| orders | order | 15 | 订单主表 |
| order_items | order_list | 67 | 订单详情 |
| profit_money | profit_money | 26,061 | 余额明细 |
| profit_integral | profit_integral | 33,487 | 积分明细 |
| diamond_orders | diamond_orders | 398 | 钻石订单 |
## Correctness Properties
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
### Property 1: 表结构完整性
*For any* 核心业务表迁移脚本执行后SQL Server 中应存在对应的表,且表结构(字段名、数据类型、约束)符合设计规范。
**Validates: Requirements 1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4**
### Property 2: 数据记录数一致性
*For any* 迁移的表,目标数据库中的记录数应与源数据库中的记录数完全一致。
**Validates: Requirements 1.5, 11.1**
### Property 3: 时间戳转换正确性
*For any* Unix 时间戳字段,转换为 DATETIME2 后应能正确还原为原始时间戳值误差不超过1秒
**Validates: Requirements 1.6**
### Property 4: 财务数据一致性
*For any* 财务相关数据(用户余额、积分、订单金额),迁移后的总和应与源数据库完全一致。
**Validates: Requirements 4.7, 11.2, 11.3**
### Property 5: 业务配置完整性
*For any* 商品的福利屋配置和限购配置,迁移后应保留所有配置值不变。
**Validates: Requirements 2.6, 2.7, 3.5**
### Property 6: 索引和约束完整性
*For any* 设计中定义的索引和约束,迁移脚本执行后应在目标数据库中正确创建。
**Validates: Requirements 12.1, 12.2, 12.3, 12.4**
### Property 7: 数据迁移往返一致性
*For any* 迁移的数据记录,从源数据库导出后导入目标数据库,再导出进行对比,关键字段值应完全一致。
**Validates: Requirements 5.4, 6.3**
## Error Handling
### 迁移错误处理策略
| 错误类型 | 处理方式 | 回滚策略 |
|---------|---------|---------|
| 表创建失败 | 记录错误,停止迁移 | 删除已创建的表 |
| 数据导入失败 | 记录失败记录,继续迁移 | 清空目标表数据 |
| 数据类型转换失败 | 使用默认值或 NULL | 标记异常记录 |
| 外键约束失败 | 延迟创建外键 | 删除外键约束 |
| 验证失败 | 生成差异报告 | 重新迁移差异数据 |
### 回滚方案
```sql
-- 紧急回滚脚本
-- 1. 删除所有已创建的表
-- 2. 恢复 MySQL 连接配置
-- 3. 验证 MySQL 数据完整性
```
## Testing Strategy
### 测试方法
本项目采用双重测试策略:
1. **单元测试**:验证单个迁移脚本的正确性
2. **属性测试**:验证迁移后数据的完整性和一致性
### 单元测试范围
- 表结构创建脚本测试
- 数据类型转换函数测试
- 字段映射规则测试
- 索引创建脚本测试
### 属性测试配置
- **测试框架**SQL Server T-SQL 脚本
- **最小迭代次数**:每个属性至少验证 100 条记录
- **测试标签格式**`-- Feature: database-migration, Property N: {property_text}`
### 验证脚本示例
```sql
-- Feature: database-migration, Property 2: 数据记录数一致性
-- 验证所有表的记录数是否一致
DECLARE @validation_results TABLE (
table_name NVARCHAR(100),
source_count INT,
target_count INT,
is_match BIT
);
-- 对比每个表的记录数
INSERT INTO @validation_results
SELECT 'users',
(SELECT COUNT(*) FROM mysql_linked_server.youdas.dbo.user),
(SELECT COUNT(*) FROM users),
CASE WHEN (SELECT COUNT(*) FROM mysql_linked_server.youdas.dbo.user) =
(SELECT COUNT(*) FROM users) THEN 1 ELSE 0 END;
-- 输出验证结果
SELECT * FROM @validation_results WHERE is_match = 0;
```
### 数据验证检查点
| 检查点 | 验证内容 | 通过标准 |
|-------|---------|---------|
| CP1 | 表结构完整性 | 所有表创建成功 |
| CP2 | 记录数一致性 | 所有表记录数匹配 |
| CP3 | 财务数据一致性 | 余额/积分/金额总和匹配 |
| CP4 | 时间戳转换 | 随机抽样100条验证 |
| CP5 | 索引和约束 | 所有索引/约束创建成功 |