对比数据库(表、列)之间的差异及成生DDL

最后更新:2024-09-30 10:38:49 | 状态:已完成

对比结果一般分3部分:删除部分、新添加部分、更新部分
示例源码

注意:

  1. 生成的SQL并不能真实还原数据库修改过程,最大的障碍在于不能捕获名称的修改过程以及先后,会导致:
    1) 实际操作的是alter,但生成的是drop+add
    2) 有依赖关系的操作如索引与名,自境与主键等,执行顺序不对会造成冲突
  2. 默认不比较catalog与schema
  • TablesDiffer
    两个数据库表列表之间的差别,就是用一个A库所有的表与B库所有的表对比
    先分别查出A B两个库中的所有表
    LinkedHashMap<String, Table> as= serviceA.metadata().tables();
    LinkedHashMap<String, Table> bs= serviceB.metadata().tables();
    然后调用TablesDiffer静态方法
    public static TablesDiffer compare(LinkedHashMap<String, Table> as, LinkedHashMap<String, Table> bs)
    返回的结果中同B库相对于A库的表删除了哪几个、添加了哪几个、更新了哪几个
  • TableDiffer
    两个表之间的差别
    表之间对比会有好几分部内容对应了几个属性,如
    1)ColumnsDiffer:两个表列之间的差别
    2)IndexsDiffer:两个表之间索引的差别
    先查出每个表的元数据,直接调用Table.compare对比
    Table a = service.metadata().table("a")
    Table b = service.metadata().table("b")
    TableDiffer differ = a.compare(b);
    或者
    TableDiffer differ = TableDiffer.compare(a, b);


LinkedHashMap<String, Table> as = ServiceProxy.metadata().tables(1, true);
LinkedHashMap<String, Table> bs = ServiceProxy.service("pg").metadata().tables(1, true);
//对比过程 默认忽略catalog, schema
TablesDiffer differ = TablesDiffer.compare(as, bs);

System.out.println("===================================== DDL ================================================");
//设置生成的SQL在源库还是目标库上执行
differ.setDirect(MetadataDiffer.DIRECT.ORIGIN);
List<Run> runs = ServiceProxy.ddl(differ);
for(Run run:runs){
	System.out.println(run.getFinalExecute()+";\n");
}

//以下在实际应用中不需要,只是为了说明详细过程
LinkedHashMap<String, Table> adds =  differ.getAdds();
System.out.println("原表"+as);
System.out.println("表表"+bs);
//由a > b
System.out.println("++++++++++++++++++++++++++++++++++++++++++添加表++++++++++++++++++++++++++++++++++++++");
for(Table item:adds.values()){
	System.out.println(item);
}
LinkedHashMap<String, Table> alters = differ.getAlters();
System.out.println("///////////////////////////////////////////修改表/////////////////////////////////////");
for(Table item:alters.values()){
	System.out.println(item);
}

LinkedHashMap<String, TableDiffer> differs = differ.getDiffers();
for(TableDiffer dif:differs.values()){
	System.out.println("修改表:"+dif.getOrigin() +" > "+dif.getDest());
	ColumnsDiffer columnsDiffer = dif.getColumnsDiffer();
	for(Column column:columnsDiffer.getAdds().values()){
		System.out.println("+添加列:"+column);
	}
	for(Column column:columnsDiffer.getAlters().values()){
		System.out.println("/修改列:"+column+" > "+column.getUpdate());
	}
	for(Column column:columnsDiffer.getDrops().values()){
		System.out.println("-删除列:"+column);
	}

}
LinkedHashMap<String, Table> drops = differ.getDrops();
System.out.println("---------------------------------------------删除表----------------------------------------");
for(Table item:drops.values()){
	System.out.println(""+item);
}
生成的日志大概如下


原表{A=TABLE:simple.a, A2=TABLE:simple.a2, B=TABLE:simple.b, C=TABLE:simple.c}
表表{A=TABLE:simple.public.a, B=TABLE:simple.public.b, D=TABLE:simple.public.d}
++++++++++++++++++++++++++++++++++++++++++添加表++++++++++++++++++++++++++++++++++++++
TABLE:simple.public.d
///////////////////////////////////////////修改表/////////////////////////////////////
TABLE:simple.a
TABLE:simple.b
修改表:TABLE:simple.a > TABLE:simple.public.a
+添加列:id INT8 default nextval('bs_array_id_seq'::regclass)
+添加列:array_int INT8[]
+添加列:array_ints INT4[]
+添加列:array_char VARCHAR[]
/修改列:cc DECIMAL(10) > cc VARCHAR[]
-删除列:CODE DOUBLE(100,2)
-删除列:d DECIMAL(10)
修改表:TABLE:simple.b > TABLE:simple.public.b
+添加列:name VARCHAR(20)
/修改列:ID INT > id INT4
/修改列:CODE INT > code VARCHAR(20)
---------------------------------------------删除表----------------------------------------
TABLE:simple.a2
TABLE:simple.c
===================================== DDL ================================================
CREATE TABLE IF NOT EXISTS simple.public.d(
	id INT AUTO_INCREMENT COMMENT '主键'
	,code VARCHAR(10) NULL COMMENT '编号'
	,price NUMERIC(22,1) NULL
	,salary NUMERIC NULL
	,salary1 NUMERIC(10) NULL COMMENT '工资1'
	,salary2 NUMERIC(10,2) NULL COMMENT '工资2'
	,types VARCHAR(100) NULL);

ALTER TABLE simple.a
ADD COLUMN id BIGINT COMMENT '主键'
,ADD COLUMN array_int BIGINT[] NULL
,ADD COLUMN array_ints INT[] NULL
,ADD COLUMN array_char VARCHAR[] NULL
,MODIFY cc VARCHAR[] NULL
,DROP COLUMN CODE
,DROP COLUMN d;

ALTER TABLE simple.b
ADD COLUMN name VARCHAR(20) NOT NULL
,MODIFY ID INT NOT NULL
,MODIFY CODE VARCHAR(20) NOT NULL;

DROP TABLE IF EXISTS simple.a2;

DROP TABLE IF EXISTS simple.c;


首页 最近更新 搜索 提交 回复