8.8 KiB
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
迁移架构图
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
迁移流程
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)
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
实体关系图
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 | 标记异常记录 |
| 外键约束失败 | 延迟创建外键 | 删除外键约束 |
| 验证失败 | 生成差异报告 | 重新迁移差异数据 |
回滚方案
-- 紧急回滚脚本
-- 1. 删除所有已创建的表
-- 2. 恢复 MySQL 连接配置
-- 3. 验证 MySQL 数据完整性
Testing Strategy
测试方法
本项目采用双重测试策略:
- 单元测试:验证单个迁移脚本的正确性
- 属性测试:验证迁移后数据的完整性和一致性
单元测试范围
- 表结构创建脚本测试
- 数据类型转换函数测试
- 字段映射规则测试
- 索引创建脚本测试
属性测试配置
- 测试框架:SQL Server T-SQL 脚本
- 最小迭代次数:每个属性至少验证 100 条记录
- 测试标签格式:
-- Feature: database-migration, Property N: {property_text}
验证脚本示例
-- 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 | 索引和约束 | 所有索引/约束创建成功 |