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

8.8 KiB
Raw Blame History

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

测试方法

本项目采用双重测试策略:

  1. 单元测试:验证单个迁移脚本的正确性
  2. 属性测试:验证迁移后数据的完整性和一致性

单元测试范围

  • 表结构创建脚本测试
  • 数据类型转换函数测试
  • 字段映射规则测试
  • 索引创建脚本测试

属性测试配置

  • 测试框架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 索引和约束 所有索引/约束创建成功