数据迁移

数据迁移是啥

数据迁移是指将数据从一个数据表迁移到另一个数据表的过程。

在本文中,介绍了两种数据迁移方案:

  • 方案一: 使用mysql View 将旧表迁移到新表
  • 方案二: 使用 JavaScript 脚本将旧表迁移到新表

模拟需求

有一张老的数据表student 和一张新的数据库表student_new,表结构如下:

  1. -- old
  2. CREATE TABLE `student` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `studentId` varchar(255) DEFAULT NULL COMMENT '学生ID',
  5. `name` varchar(255) DEFAULT NULL COMMENT '学生名字',
  6. `gender` varchar(255) DEFAULT NULL COMMENT '性别',
  7. `dateOfBirth` varchar(255) DEFAULT NULL COMMENT '出生日期',
  8. `classId` varchar(255) DEFAULT NULL COMMENT '班级ID',
  9. `level` varchar(255) DEFAULT NULL COMMENT '年级',
  10. `bodyHeight` varchar(255) DEFAULT NULL COMMENT '身高',
  11. `studentStatus` varchar(255) DEFAULT NULL COMMENT '学生状态',
  12. `remarks` mediumtext COMMENT '备注',
  13. `operation` varchar(255) DEFAULT 'insert' COMMENT '操作; insert, update, jhInsert, jhUpdate, jhDelete jhRestore',
  14. `operationByUserId` varchar(255) DEFAULT NULL COMMENT '操作者userId',
  15. `operationByUser` varchar(255) DEFAULT NULL COMMENT '操作者用户名',
  16. `operationAt` varchar(255) DEFAULT NULL COMMENT '操作时间; E.g: 2021-05-28T10:24:54+08:00 ',
  17. PRIMARY KEY (`id`) USING BTREE,
  18. KEY `studentId` (`studentId`) USING BTREE
  19. ) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8mb4;
  20. -- new
  21. CREATE TABLE `student_new` (
  22. `id` int(11) NOT NULL AUTO_INCREMENT,
  23. `studentId` varchar(255) DEFAULT NULL COMMENT '学生ID',
  24. `studentName` varchar(255) DEFAULT NULL COMMENT '学生名字',
  25. `studentGender` varchar(255) DEFAULT NULL COMMENT '性别',
  26. `dateOfBirth` varchar(255) DEFAULT NULL COMMENT '出生日期',
  27. `classId` varchar(255) DEFAULT NULL COMMENT '班级ID',
  28. `level` varchar(255) DEFAULT NULL COMMENT '年级',
  29. `bodyHeight` varchar(255) DEFAULT NULL COMMENT '身高',
  30. `studentStatus` varchar(255) DEFAULT NULL COMMENT '学生状态',
  31. `remarks` mediumtext COMMENT '备注',
  32. `operation` varchar(255) DEFAULT 'insert' COMMENT '操作; insert, update, jhInsert, jhUpdate, jhDelete jhRestore',
  33. `operationByUserId` varchar(255) DEFAULT NULL COMMENT '操作者userId',
  34. `operationByUser` varchar(255) DEFAULT NULL COMMENT '操作者用户名',
  35. `operationAt` varchar(255) DEFAULT NULL COMMENT '操作时间; E.g: 2021-05-28T10:24:54+08:00 ',
  36. PRIMARY KEY (`id`) USING BTREE,
  37. KEY `studentId` (`studentId`) USING BTREE
  38. ) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8mb4;

需求:将student数据迁移至student_new

方案一: 使用mysql View将旧表迁移到新表的方案

  • 第一步: 使用mysql view将新表的数据准备好
    1. DROP VIEW IF EXISTS `view01_migrate_student_new`;
    2. CREATE VIEW view01_migrate_student_new AS
    3. SELECT
    4. `student`.`id` AS `id`,
    5. `student`.`studentId` AS `studentId`,
    6. `student`.`name` AS `studentName`,
    7. `student`.`gender` AS `studentGender`,
    8. `student`.`dateOfBirth` AS `dateOfBirth`,
    9. `student`.`classId` AS `classId`,
    10. `student`.`level` AS `level`,
    11. `student`.`bodyHeight` AS `bodyHeight`,
    12. `student`.`studentStatus` AS `studentStatus`,
    13. `student`.`remarks` AS `remarks`,
    14. `student`.`operation` AS `operation`,
    15. `student`.`operationByUserId` AS `operationByUserId`,
    16. `student`.`operationByUser` AS `operationByUser`,
    17. `student`.`operationAt` AS `operationAt`
    18. FROM
    19. `student`;
  • 第二步: 将view01_migrate_student_new 写入到student_new
    1. -- 多次执行需要删除上一次的数据
    2. INSERT INTO student_new SELECT * FROM view01_migrate_student_new;

方案二: 使用 JavaScript 脚本将旧表迁移到新表

使用脚本是一种比较笨的方法,但是也是一种兼容性最高的方法,可以方便的处理任何数据结构差异带来的数据问题

  1. const knex = require('knex')({
  2. client: 'mysql',
  3. connection: {
  4. host: 'source_database_host',
  5. user: 'source_database_username',
  6. password: 'source_database_password',
  7. database: 'source_database_name'
  8. }
  9. });
  10. async function migrateData() {
  11. const oldList = await knex('student').select();
  12. const newList = oldList.map(old => {
  13. const { name: studentName, gender: studentGender, ...other } = old;
  14. return { studentName, studentGender, ...other };
  15. })
  16. // 注意: 多次执行需要删除上一次的数据
  17. await targetDb('student_new').insert(newList);
  18. }