285 lines
8.8 KiB
Markdown
285 lines
8.8 KiB
Markdown
# 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 | 索引和约束 | 所有索引/约束创建成功 |
|