4. 数据存储设计:文件存储(JSON/YAML)、数据库存储(MySQL/Redis)、存储格式对比

数据回放的核心,说白了就是「存」和「读」两个字。

你想想看,我们辛辛苦苦录制了一堆接口请求、页面操作、数据库状态,如果存得乱七八糟,回放时根本没法用。我个人习惯是,先想清楚数据要存成什么样,再动手写代码。这一章,我就把几种主流存储方案掰开揉碎了讲给你听。

4.1 文件存储:JSON vs YAML

文件存储是最直接的方式。不需要安装数据库,一个文本文件就能搞定。我早期做测试框架时,就靠 JSON 文件撑过了大半年。

4.1.1 JSON 存储

JSON 的优势是「通用」。几乎所有语言都原生支持,解析起来零成本。我在项目中遇到过,团队里有人用 Python,有人用 Java,最后统一用 JSON 交换数据,谁都不用装额外库。

JSON 存储示例:

{
  "session_id": "2024-03-15-001",
  "timestamp": 1710489600,
  "steps": [
    {
      "action": "click",
      "selector": "#login-btn",
      "value": null
    },
    {
      "action": "input",
      "selector": "#username",
      "value": "test_user"
    }
  ]
}

但 JSON 有个坑——不支持注释。你想想看,一个回放脚本跑半年后,谁还记得某个字段是干嘛的?我曾经因为这个吃过亏,后来不得不额外写一个 README 文件来解释字段含义。

4.1.2 YAML 存储

YAML 就友好多了。它支持注释,结构也更清晰。我个人习惯用 YAML 存配置型数据,比如回放的环境参数、超时设置等。

YAML 存储示例:

session:
  id: "2024-03-15-001"
  timestamp: 1710489600
  # 这里是回放时的等待策略
  wait_strategy: "smart"

steps:
  - action: click
    selector: "#login-btn"
    # 这个元素有时加载慢,加了重试
    retry: 3
  - action: input
    selector: "#username"
    value: "test_user"

我的建议:如果数据量小(几千条以内),用 YAML 存配置,用 JSON 存纯数据。别混着用,否则维护起来很痛苦。

4.2 数据库存储:MySQL vs Redis

当数据量上来后,文件存储就不够看了。我记得有一次,回放数据到了 10 万条,用 JSON 文件加载一次要 3 秒,回放一次要 30 秒——这谁受得了?

4.2.1 MySQL 存储

MySQL 适合存「结构化」的回放数据。比如每个请求的 URL、参数、响应码、耗时等。你可以建一张表,把每次回放的结果都记下来,方便后续分析。

MySQL 表结构示例:

CREATE TABLE replay_records (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    session_id VARCHAR(64) NOT NULL,
    step_index INT NOT NULL,
    action_type VARCHAR(32),
    selector VARCHAR(255),
    input_value TEXT,
    response_code INT,
    response_body TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_session (session_id)
);

我在项目中遇到过,用 MySQL 存回放数据后,查询某个 session 的所有步骤只需要 0.01 秒。而且可以很方便地做统计分析——比如「哪个接口最容易超时」。

注意:MySQL 不适合存「大文本」数据。如果响应体动不动就几 MB,建议只存路径,把实际内容放到文件系统里。

4.2.2 Redis 存储

Redis 是内存数据库,速度极快。适合存「临时」的回放数据,比如正在回放中的状态、缓存的结果等。

Redis 存储示例:

# 用 Hash 存单个步骤
HSET replay:session:2024-03-15-001 step:1 action click
HSET replay:session:2024-03-15-001 step:1 selector "#login-btn"

# 用 List 存步骤顺序
LPUSH replay:session:2024-03-15-001:steps step:1 step:2 step:3

# 用 String 存回放状态
SET replay:status:2024-03-15-001 "running"

我曾经用 Redis 做过一个实时回放系统,数据写入速度比 MySQL 快 100 倍。但要注意,Redis 的数据是存在内存里的,重启就丢了。所以我的习惯是:Redis 做缓存,MySQL 做持久化。

4.3 存储格式对比

说了这么多,到底该选哪个?我整理了一张对比表,你一看就明白。

特性 JSON YAML MySQL Redis
读写速度 中等 较慢 中等 极快
数据量支持 小(万级) 小(千级) 大(亿级) 中(百万级)
可读性 一般 好 差(需工具) 差(需工具)
支持注释 否 是 是(字段注释) 否
持久化 是 是 是 可选
查询能力 无 无 强(SQL) 中等(Key-Value)
适用场景 数据交换、小规模存储 配置文件 持久化、统计分析 缓存、实时状态

我的选择策略:

  • 单次回放数据量 < 1000 条 → 用 JSON 文件,简单直接
  • 需要长期保存、分析 → 用 MySQL,建好索引
  • 需要实时回放、高并发 → 用 Redis 做缓存层
  • 配置文件 → 用 YAML,可读性第一

4.4 知识体系结构图

下面这张图,把本章的核心逻辑串起来了。你可以看到,数据从录制到回放,经历了「采集→存储→读取→回放」四个阶段,每个阶段都有对应的存储方案。

数据回放存储设计知识体系 数据采集 存储决策 存储方案 JSON 文件 数据交换 小规模存储 YAML 文件 配置文件 可读性优先 MySQL 持久化存储 统计分析 Redis 缓存加速 实时状态 数据读取与解析 回放执行

避坑指南:我曾经犯过一个错误——把所有回放数据都存到 Redis 里,结果服务器重启后数据全丢了,导致一上午的录制白干了。后来我学乖了:Redis 只存「当前正在回放」的数据,历史数据一律落盘到 MySQL 或文件里。

嗯,存储设计这块,说白了就是「权衡」。没有银弹,只有最适合你场景的方案。我个人建议,刚开始做数据回放时,先用 JSON 文件跑通流程,等数据量上来了再迁移到数据库。别一上来就上 MySQL+Redis,容易把自己搞晕。

可可精品资料库