likes
comments
collection
share

MySQL「08」使用 synth 生成随机数据

作者站长头像
站长
· 阅读数 13

之前的几篇文章都在学习 MySQL 或 InnoDB 数据引擎中的一些底层原理,内容也比较“严肃”。 今天,我们来学一点“轻松”点的内容,如何向 MySQL 数据库表中插入一些伪数据或模拟数据。 在开发阶段或测试阶段初期,对这些模拟数据的需求还是比较强烈的。 例如,我们开发好了一个功能,为了测试其效果,往往需要向数据库中插入一些模拟的数据。 一般我们会采用随机生成,或者手工录入的方式,但这对开发者来说就像是一个噩梦。

今天我们将学习如何借助一个开源工具来帮助我们生成模拟数据。

01-synth 简介

synth 是一个开源的数据生成器,可以根据一定的规则来生成数据。 synth 官网对自己的定义是:

Synth is an open source data-as-code tool that provides a simple CLI workflow for generating consistent data in a scalable way.

简单来说,synth 可以根据符合 synth schema 规范的数据模型描述(JSON 文件)来生成数据(JSON 格式)。 例如,官网中提供的 hello_synth/say_hello.json 示例,它定义了一个数据模型:

{
    "type": "array",
    "length": {
        "type": "number",
        "subtype": "u64",
        "constant": 1
    },
   "content": {
        "type": "string",
        "pattern": "Hello world!"
    }
}

根据上述模型,synth 可以生成符合上述模型要求的数据记录。

synth generate hello_synth

# 输出如下
# ["Hello world!"]

02-基本概念定义

02.1-Namespace

Namespace 是 synth 中最高层次的抽象。 类似于关系型数据库中的 Schema,例如 MySQL 中的 database。 某个 namespace 内的 filed 之间可以互相引用,跨 namespace 之间的不行。

从文件系统的角度看,namespace 是文件系统中的文件夹,synth 从中读取 collection 定义。 例如,上节中 hello_synth 就是一个 namespace。

02.2-Collection

每个 namespace 中包含0或多个 collection,类似于关系性数据库中的 table。

从文件系统角度看,collection 是 *.json 文件,且必须遵守 synth 中对内容格式的定义、最外层为 Array。 synth 通过文件名来定位到对应的 .json 文件。

例如,hello_synth/say_hello.json 表示 namespace 为 hello_synth,名为 say_hello 的 collection。

02.4-Field

每个 collection 由若干个 field 组成。 Field 描述了两部分内容:

  1. 数据中的字段,它表示生成的数据中对应的字段信息。
  2. 字段的类型,以及使用哪个 generator 来生成这个数据等信息。

例如:

"phone_number": {
    "type": "string",
    "faker": {
        "generator": "cell_number"
    }
},

Field 引用,是一种 field 类型,它描述 collection 中不同部分,甚至是 namespace 中多个 collection 之间的关系。 引用可以理解为一种“地址”,形式为:<collection_name>.<level_0>.<level_1>...

02.4-schema

Schema 表示数据模型,通过它来告诉 synth 如何生成数据。 Schema 由一系列的 generators 组成。

上述这些概念之间的关系如下图所示:

MySQL「08」使用 synth 生成随机数据

简单解释一下同种的内容:

  1. namespace 为 my_app,下面包含两个 collection:transactions 和 users。 从文件系统的角度看就是,my_app 目录下有两个 JSON 文件,transactions.json 和 users.json。
  2. 以 users 为例,它定义数据模型 users 包含两个内容,user_id 和 user_email。 id 和 Faker::Email 是两种 synth 内置的 generator,用来生成看似有意义的 id 和 e-mail。

使用上述 namespace 生成的数据示例如下:

{
    "transactions": [
        {
            "amount": 870.66, 
            "currency": "GBP", 
            "timestamp": "2019-07-17T09:00:05+0000", 
            "user_id": 1
        }
    ], 
    "users": [
        {
            "user_email": "archibald@example.net", 
            "user_id": 1
        }
    ]
}

是不是乍看上去与真实数据非常相似。

02.5-synth 架构图

MySQL「08」使用 synth 生成随机数据

从图中看出,synth 主要分为两部分功能,import 和 generate。

  • import 将 schema 定义加载到 synth 中,这里支持三种类型输入文件,json 文件、PostgreSQL 表、MySQL 表。 其中,以 PostgreSQL 表、MySQL 表作为输入源,会先转换为 json 文件。 例如:
synth import --from mysql://<user>:<password>@localhost:3306/synth --schema users my_namespace
// 会将 MySQL 中 database synth 中的 users 表导出到文件系统中 my_namespace/users.json 中
// 其原理是:
// SELECT
//      table_name,
//      column_name,
//      referenced_table_name,
//      referenced_column_name
// FROM
//      information_schema.key_column_usage
// WHERE
//      referenced_table_schema = DATABASE()
  • generate 读取 *.json 文件,生成数据。 生成的数据可以输出在控制台,也可以再写回到数据库对应表中。 例如:
synth generate my_namespace --to mysql://<user>:<password>@localhost:3306/synth --schema users
// 会将生成的数据插入到数据库中
// 其原理是:
// INSERT INTO
//      users (`city`, `phone_number`, `user_email`, `user_id`)
// VALUES
//      (?, ?, ?, ?),
//      (?, ?, ?, ?);

03-总结

好了,有了 synth,就能愉快地生成模拟数据。 快去尝试下吧,希望本篇文章能够帮助到你。