对比数据库(表、列)之间的差异及成生DDL
最后更新:2024-09-30 10:38:49
|
状态:已完成
对比结果一般分3部分:删除部分、新添加部分、更新部分
【示例源码】
注意:
-
生成的SQL并不能真实还原数据库修改过程,最大的障碍在于不能捕获名称的修改过程以及先后,会导致:
1) 实际操作的是alter,但生成的是drop+add
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;