> 数据库 > MySQL >

MySql之自动同步表结构

MySql之自动同步表结构

开发痛点

在开发过程中,由于频繁的修改数据库的字段,导致rd和qa环境的数据库表经常不一致。
而由于这些修改数据库的操作可能由多个rd操作,很难一次性收集全。人手工去和qa环境对字段又特别繁琐,容易遗漏。

解决之道

于是笔者就写了一个能够自动比较两个数据库的表结构,并生成alter语句的程序。同时还可以进行配置从而自动这行这些alter语句。详情见github

原理

同步新增的表

如果rd环境新增的表,而qa环境没有,此程序可以直接输出create table语句。原理如下:
addtable
用到的sql主要有:


  1.  
    show table from rd_db;
  2.  
    show create table added_table_name;

同步表结构

如果rd表结构有改动,而qa环境没有,此程序可以直接输出alter语句,原理如下: synctable 用到的sql有:


  1.  
    select
  2.  
    COLUMN_NAME,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,COLUMN_COMMENT,EXTRA
  3.  
    from
  4.  
    information_schema.columns
  5.  
    where
  6.  
    TABLE_SCHEMA='rd_db'
  7.  
    and TABLE_NAME = 'rd_table';

比较表结构的代码:


  1.  
    for (Column column : sourceTable.getColumns().values()) {
  2.  
    if (targetTable.getColumns().get(column.getName()) == null) {
  3.  
    // 如果对应的target没有这个字段,直接alter
  4.  
    String sql = "alter table " + target.getSchema() + "." + targetTable.getTableName() + " add " + column
  5.  
    .getName() + " ";
  6.  
    sql += column.getType() + " ";
  7.  
    if (column.getIsNull().equals("NO")) {
  8.  
    sql += "NOT NULL ";
  9.  
    } else {
  10.  
    sql += "NULL ";
  11.  
    }
  12.  
    if (column.getDefaultValue() != null) {
  13.  
    sql += "DEFAULT " + SqlUtil.getDbString(column.getDefaultValue()) + " ";
  14.  
    }
  15.  
    if (column.getComment() != null) {
  16.  
    sql += "COMMENT " + SqlUtil.getDbString(column.getComment()) + " ";
  17.  
    }
  18.  
    if (after != null) {
  19.  
    sql += "after " + after;
  20.  
    }
  21.  
    changeSql.add(sql+";");
  22.  
    } else {
  23.  
    // 检查对应的source 和 target的属性
  24.  
    String sql =
  25.  
    "alter table " + target.getSchema() + "." + targetTable.getTableName() + " change " + column
  26.  
    .getName() + " ";
  27.  
    Column sourceColumn = column;
  28.  
    Column targetColumn = targetTable.getColumns().get(sourceColumn.getName());
  29.  
    // 比较两者字段,如果返回null,表明一致
  30.  
    String sqlExtend = compareSingleColumn(sourceColumn, targetColumn);
  31.  
    if (sqlExtend != null) {
  32.  
    changeSql.add(sql + sqlExtend+";");
  33.  
    }
  34.  
    }
  35.  
    after = column.getName();
  36.  
    }

同步索引结构

如果rd表的索引有改变,而qa环境没有,此程序可以直接输出修改索引语句。原理和上面类似,在此不再赘述。

配置


  1.  
    sourceHost=127.0.0.1:3306
  2.  
    sourceUser=root
  3.  
    sourcePass=123123123
  4.  
    sourceSchema=mystique_db
  5.  
    sourceCharset=utf8
  6.  
     
  7.  
    targetHost=127.0.0.1:3306
  8.  
    targetUser=root
  9.  
    targetPass=123123123
  10.  
    targetSchema=mystique_test
  11.  
    targetCharset=utf8
  12.  
     
  13.  
    autoExecute=YES //此处表明自动同步

运行

按照上面的模板进行配置 用IDE打开,找到

alchemystar.runner.ShellRunner 

运行其中的main方法即可

生成效果展示


  1.  
    alter table mystique_test.t_test_3 change id id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ''
  2.  
    alter table mystique_test.t_test_3 add index (name)
  3.  
    alter table mystique_test.t_test_3 drop index name_id
  4.  
    alter table mystique_test.t_test_3 add id_2 varchar(50) NULL DEFAULT '' COMMENT '' after name

如果打开了自动执行,会自动执行这些语句

github链接

https://github.com/alchemystar/Lancer

码云链接

https://git.oschina.net/alchemystar/Lancer

原文链接

https://my.oschina.net/alchemystar/blog/858996

(责任编辑:IT)