3. 环境准备:搭建MySQL测试环境、准备样本数据集(订单表、用户表)
在开始SQL回测规则与灰度切换之前,必须构建一个隔离、可重复的测试环境。本章将指导你完成MySQL单机测试环境的搭建,并创建核心的订单表与用户表样本数据集,为后续的回测执行提供数据基础。
3.1 测试环境规格与版本选择
为保证回测结果的稳定性与可移植性,建议使用以下统一规格。生产环境与测试环境的版本差异应控制在次要版本内。
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| MySQL | 8.0.32+ | 支持窗口函数、CTE,便于回测规则编写 |
| 操作系统 | CentOS 7.9 / Ubuntu 22.04 | 生产环境常用发行版 |
| 存储引擎 | InnoDB | 支持事务与行级锁,模拟真实并发 |
| 字符集 | utf8mb4 | 避免emoji或特殊字符截断 |
| 时区 | +08:00 (Asia/Shanghai) | 订单时间字段依赖时区设置 |
环境隔离建议:使用Docker容器或独立的MySQL实例,避免与开发/生产库混用。回测过程中可能涉及大量临时表与索引变更,隔离环境可防止误操作。
3.2 搭建MySQL测试实例(Docker快速部署)
以下步骤使用Docker在本地快速拉起一个干净的MySQL 8.0测试实例,适用于个人笔记本或CI/CD流水线。
# 拉取官方镜像
docker pull mysql:8.0.32
# 启动容器,挂载数据目录与配置
docker run -d \
--name mysql_retest \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=Retest@2025 \
-e MYSQL_DATABASE=regression_db \
-v /data/mysql_retest:/var/lib/mysql \
mysql:8.0.32 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci \
--default-time_zone='+8:00'
# 验证连接
mysql -h 127.0.0.1 -P 3307 -u root -pRetest@2025
端口冲突注意:本地MySQL默认端口为3306,测试容器映射到3307,避免与已有服务冲突。若生产环境使用不同端口,请相应调整。
3.3 样本数据集设计:用户表与订单表
回测规则通常涉及用户维度与订单维度的关联分析。两张表的设计需覆盖主键、索引、时间戳、状态枚举等关键字段,以便后续测试索引选择、分区裁剪、JOIN优化等场景。
3.3.1 用户表(users)
CREATE TABLE `users` (
`user_id` int NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`user_name` varchar(64) NOT NULL COMMENT '用户名',
`register_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',
`user_level` tinyint NOT NULL DEFAULT '1' COMMENT '用户等级:1-普通,2-VIP,3-至尊',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态:1-正常,0-冻结',
`last_login` datetime DEFAULT NULL COMMENT '最后登录时间',
PRIMARY KEY (`user_id`),
KEY `idx_register_date` (`register_date`),
KEY `idx_user_level` (`user_level`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
3.3.2 订单表(orders)
CREATE TABLE `orders` (
`order_id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`user_id` int NOT NULL COMMENT '用户ID',
`order_amount` decimal(12,2) NOT NULL COMMENT '订单金额',
`order_status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态:0-待支付,1-已支付,2-已发货,3-已完成,4-已取消',
`pay_time` datetime DEFAULT NULL COMMENT '支付时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`order_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_create_time` (`create_time`),
KEY `idx_order_status` (`order_status`),
CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
设计要点:
- 订单表使用
bigint主键,避免int溢出(生产环境订单量级通常较大)。 - 外键
fk_user_id保证数据完整性,回测时可临时禁用外键检查以提升批量插入性能:SET foreign_key_checks = 0;。 - 时间字段均使用
datetime类型,配合+8:00时区,避免timestamp的2038年问题。
3.4 样本数据生成与导入
为模拟真实数据分布,使用存储过程批量生成100万用户与500万订单数据。数据生成策略需覆盖热点用户、时间倾斜、状态分布等特征,使回测规则能暴露真实性能问题。
-- 生成100万用户
DELIMITER $$
CREATE PROCEDURE generate_users(IN num INT)
BEGIN
DECLARE i INT DEFAULT 1;
SET @batch_size = 10000;
WHILE i <= num DO
INSERT INTO users (user_name, register_date, user_level, status)
SELECT
CONCAT('user_', i + seq),
DATE_SUB(NOW(), INTERVAL FLOOR(RAND() * 365) DAY),
FLOOR(1 + RAND() * 3),
IF(RAND() < 0.95, 1, 0)
FROM (SELECT @i := @i + 1 AS seq FROM (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) a,
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) b,
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) c,
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) d) tmp
WHERE seq <= @batch_size;
SET i = i + @batch_size;
END WHILE;
END$$
DELIMITER ;
CALL generate_users(1000000);
-- 生成500万订单(关联用户ID 1~100万)
INSERT INTO orders (user_id, order_amount, order_status, pay_time, create_time)
SELECT
FLOOR(1 + RAND() * 1000000),
ROUND(RAND() * 5000 + 10, 2),
FLOOR(0 + RAND() * 5),
CASE WHEN RAND() < 0.8 THEN DATE_SUB(NOW(), INTERVAL FLOOR(RAND() * 180) DAY) ELSE NULL END,
DATE_SUB(NOW(), INTERVAL FLOOR(RAND() * 200) DAY)
FROM
(SELECT a.seq FROM (SELECT @i := @i + 1 AS seq FROM information_schema.COLUMNS a,
information_schema.COLUMNS b LIMIT 5000000) a) tmp;
数据分布验证:生成完成后,执行以下查询确认数据倾斜度:
若某状态占比过低(如已取消订单不足1%),可调整生成逻辑中的随机概率。
SELECT user_level, COUNT(*) FROM users GROUP BY user_level;SELECT order_status, COUNT(*) FROM orders GROUP BY order_status;若某状态占比过低(如已取消订单不足1%),可调整生成逻辑中的随机概率。
3.5 测试环境拓扑与数据流向
下图展示了测试环境的逻辑拓扑,以及回测过程中SQL语句的流转路径。数据从样本库出发,经过回测引擎解析后,在测试实例上执行并收集性能指标。
3.6 环境验证清单
完成搭建后,逐项确认以下检查点,确保环境符合回测要求:
- 连接测试:使用
mysql -h 127.0.0.1 -P 3307 -u root -p成功登录。 - 数据库确认:
SHOW DATABASES;包含regression_db。 - 表结构验证:
DESC users;与DESC orders;字段与设计一致。 - 数据量检查:
SELECT COUNT(*) FROM users;返回 1,000,000;SELECT COUNT(*) FROM orders;返回 5,000,000。 - 索引状态:
SHOW INDEX FROM orders;确认包含idx_user_id、idx_create_time、idx_order_status。 - 时区验证:
SELECT NOW();返回当前东八区时间。
快照建议:在数据生成完成后,使用
mysqldump或CLONE PLUGIN创建一份初始快照。每次回测前恢复快照,确保不同规则版本在完全相同的数据集上执行,消除数据变化带来的干扰。