0x00

首先简单解释一下「Data Migration」和「DSL」。

Data Migration 是一种对数据进行选择,准备,抽取和转换操作的系列流程,最终结果是,旧系统的数据被迁移到不同数据结构的新系统上。

DSL (Domain Specific Language) 则是一种面向特定领域的语言,例如在解决 Gradle 配置这个问题域中,就现在分别有基于 GroovyKotlin 的两套不同 DSL。

0x01

前段时间,一个替换旧系统的项目就面临了 Data Migration 的需求。其实团队之前就已经有过几次类似的经验了,面临的根本问题都是:

  • 新旧两套系统的数据设计完全不同,业务流程也有差异
  • 旧系统的数据库数据不能直接暴露,只能在用户界面上导出 Excel

而基于上面的条件限制,想简单地通过数据库进行 Migration 并不可能实现。所以,已有的解决方案是根据每次 Migration 的业务要求,来编写 Migration Script,再将多处调用的方法提取到 Common Module。

但是这样的实践,即使复用了部分的逻辑,不同的开发依然会写出风格各异的 Migration Script。这也意味着后面每做一轮新的 Migration,就会有一套新的轮子。

为了解决这个 特定的问题域,便设计了一套 新的轮子 「Data Migration DSL」。

0x02

先鸟瞰整个 Migration Script,把它当作一个 Function:

       migration excel   +----------------------+                  
  ---------------------->|                      |   migrated sql   
                         |   Migration script   |----------------> 
  ---------------------->|                      |   logging file   
 mapping configuration   +----------------------+                  

简化了 Migration 的实际需求,只会关注到一些关键信息

与之对应的输入是:

  • migration excel 是旧系统导出的 Excel 数据
  • mapping configuration 是两套系统的中各类 Dropdown 的映射配置
  • 省略了其他的配置信息

输出是:

  • migrated sql 是需要插入到新系统的 SQL 文件
  • logging file 主要记录程序的运行记录,包括 Data Clean, Data Validation 以及其他流程的记录信息
  • 省略了其他生成的信息

0x03

往这个 Function 中走进一些:

                                                                                             +-------------+                 
                                                                                             |             |   migrated sql  
                                                                                             |    Output   |---------------->
                                                                                             |             |                 
                                                                                             +-------------+                 
                                                                                                    ^                        
                         +-----------+          +--------------------------------+                  |                        
       migration excel   |           |   pipe   |                                |------------------+                        
  ---------------------->|   Input   |--------->|   Models (with dependencies)   |  migrated result                          
 mapping configuration   |           |          |                                |------------------+                        
                         +-----------+          +--------------------------------+                  |                        
                                                                                                    v                        
                                                                                             +-------------+                 
                                                                                             |             |   logging file  
                                                                                             |   Logging   |---------------->
                                                                                             |             |                 
                                                                                             +-------------+                 

内部由以下四个模块来实现 Migration 流程:

  • Input 处理输入的数据

    • 将定义好格式的 mapping configuration 读到内存中,例如 Key/Value 的形式
    • 根据导入的 Excel 的结构,重新组织数据结构,并重定向到到下一步的 Models 模块中
  • Models 定义新系统的业务模型,会由多个 Model 构成

    • 每个 Model 会定义多个 property 来表示相应业务模型的字段信息
    • 每个 property 分别定义有取值,验证,转换等操作
    • 此外,多个 property 之间可能存在值引用,关联计算等依赖关系,这也是需要进行声明的
    • 从上一个模块传来的旧系统数据,便会通过上面的定义转换成新系统的业务模型,并重定向到 OutputLogging
  • Outputmigrated result 转换成具体的数据库和表上的 SQL 语句

  • Logging 统计 migrated result 的概要和程序运行时的记录

从上述模块的描述中,不难看出在整个 Data Migration DSL 中 Models 是新旧系统数据转换中最重要的一部分。同时这部分的复杂度也是和新系统的业务复杂度紧密相关的,无论采取何种实现方式都是无法消除的,只能尽量去减少。

后面将会基于以上设计和想法,实现这个 Data Migration DSL 的 Demo