MySQL diff summary:
1. When dealing with the problem, take the object-oriented method to extract the objects existing in the problem or instance.
2. When extracting the object, try to consider it as complete as possible, and separate each feature of the problem into each attribute of the object.
3. Object separation is good, and modeling is considered. The establishment of data model is very important. The quality of model determines the complexity of code writing. In the design, first find each object to be processed, then find the common ancestor of each object, abstract layer by layer, and finally establish the inheritance relationship between each class.
4. The object extraction should be detailed, starting from the whole to each subdivision, so that the problem can be handed over to the next level.
5. The attribute type of the object should be considered carefully, which can not be handled entirely by the string, and the attribute naming should be standardized, humped, meaningful and metaphorical.
6. The defined data structure shall be easy to handle and shall not be too complex, thus increasing the difficulty of programming.
public class Field { private String ColumnName; private String TableName; private Boolean IsNull; private FieldType fieldType; private String Default; private boolean IsExistField; private boolean IsPrimaryKey; private boolean IsUnique; private boolean IsAutoIncreament; }
public class Index { private String TableName; private String IndexName; private List<String> ColumnName; private boolean IsExistIndex; }
public class Table { private String TableName; private HashMap<String,Field> fieldHashMap; private HashMap<String,Index> indexHashMap; }
public class DataBase { private String name; private HashMap<String, Table> tableHashMap; private HashMap<String,TableDiff> tableDiffHashMap; }
public class TableDiff { private String TableName; private HashMap<String,FieldDiff> fieldDiffMap; private HashMap<String,Index> indexDiffMap; private boolean IsExistTable; }
public class FieldDiff { private String TableName; private String ColumnName; private Boolean IsNull; private FieldType fieldType; private String Default; private String Extra; private boolean IsExistField; private boolean IsPrimaryKey; private boolean IsUnique; private boolean IsAutoIncreament; }
7. When defining a data type, you must consider the algorithms that this type may participate in in in the future. If there are requirements for comparison and change, try not to use List for storage, and use Hash Map more, which can greatly optimize the complexity of the algorithm, so as to reduce the occurrence of loops, especially double loops or multiple loops. You can directly obtain values according to keys by using Map, and there is no need to continue cyclic search.
for (Map.Entry<String, Table> entry : SecTableMap.entrySet()) { Table MainTable = MainTableMap.get(entry.getKey()); Table SecTable = entry.getValue(); if (MainTable!=null) { TableDiff tableDiff = MainTable.diffHashMap(SecTable); tableDiff.setExistTable(true); diffHashMap.put(MainTable.getTableName(),tableDiff); } else { TableDiff tableDiff = new TableDiff(); tableDiff.setTableName(entry.getKey()); tableDiff.setExistTable(false); diffHashMap.put(entry.getKey(), tableDiff); } }
8. Modular processing and division of labor shall be considered in code writing. A certain task shall be completed by a certain class and processed hierarchically. Solutions to problems must not be stacked in one layer.
public HashMap<String,TableDiff> diffHashMap(DataBase target) { HashMap<String,TableDiff> diffHashMap = new HashMap<>(); HashMap<String,Table> MainTableMap = this.getTableHashMap(); HashMap<String,Table> SecTableMap = target.getTableHashMap(); for (Map.Entry<String, Table> entry : SecTableMap.entrySet()) { Table MainTable = MainTableMap.get(entry.getKey()); Table SecTable = entry.getValue(); if (MainTable!=null) { TableDiff tableDiff = MainTable.diffHashMap(SecTable); tableDiff.setExistTable(true); diffHashMap.put(MainTable.getTableName(),tableDiff); } else { TableDiff tableDiff = new TableDiff(); tableDiff.setTableName(entry.getKey()); tableDiff.setExistTable(false); diffHashMap.put(entry.getKey(), tableDiff); } } return diffHashMap; }
public TableDiff diffHashMap(Table second) { HashMap<String,Field> MainField = this.getFieldHashMap(); HashMap<String,Field> SecField = second.getFieldHashMap(); TableDiff tableDiff = new TableDiff(); HashMap<String,FieldDiff> fieldDiffMap = new HashMap<>(); for (Map.Entry<String, Field> entry : MainField.entrySet()) { Field main = entry.getValue(); Field sec = SecField.get(entry.getKey()); if (sec!=null) { FieldDiff fieldDiff = main.FieldDiff(sec); fieldDiff.setExistField(true); fieldDiffMap.put(main.getColumnName(),fieldDiff); } else { FieldDiff fieldDiff = new FieldDiff(); fieldDiff.setExistField(false); fieldDiff.setColumnName(entry.getKey()); fieldDiffMap.put(entry.getKey(),fieldDiff); } } HashMap<String,Index> MainIndex = this.getIndexHashMap(); HashMap<String,Index> SecIndex = second.getIndexHashMap(); HashMap<String,Index> IndexDiffMap = new HashMap<>(); for (Map.Entry<String,Index> entry : MainIndex.entrySet()) { Index main = entry.getValue(); Index sec = SecIndex.get(entry.getKey()); if (sec!=null) { Index index = main.Diff(sec); index.setExistIndex(true); IndexDiffMap.put(main.getIndexName(),index); } else { Index index = new Index(); index.setIndexName(entry.getKey()); index.setExistIndex(false); IndexDiffMap.put(entry.getKey(),index); } } tableDiff.setIndexDiffMap(IndexDiffMap); tableDiff.setFieldDiffMap(fieldDiffMap); tableDiff.setTableName(this.getTableName()); return tableDiff; }
public Index Diff(Index Sec) { Index diff = new Index(); if (this.getColumnName()!=Sec.getColumnName()) { diff.setTableName(Sec.getTableName()); diff.setColumnName(Sec.getColumnName()); diff.setIndexName(Sec.getIndexName()); } return diff; }
public FieldDiff FieldDiff(Field second) { HashMap<String,FieldDiff> fieldDiffMap = new HashMap<>(); if(this.isNull()!=second.isNull()||this.getFieldType()!=second.getFieldType()||this.getExtra()!=second.getExtra()||this.getDefault()!=second.getDefault()) { FieldDiff fieldDiff = new FieldDiff(); fieldDiff.setTableName(second.getTableName()); fieldDiff.setColumnName(second.getColumnName()); if (!this.isNull().equals(second.isNull())) { fieldDiff.setNull(second.isNull()); } if (!this.getFieldType().equals( second.getFieldType())) { fieldDiff.setFieldType(second.getFieldType()); } if (!this.getExtra() .equals(second.getExtra()) ) { fieldDiff.setExtra(second.getExtra()); } if (!this.getDefault() .equals(second.getDefault())) { fieldDiff.setDefault(second.getDefault()); } if (!this.getExtraType().equals(second.getExtraType())) { fieldDiff.setExtraType(ExtraType.AUTOINCREMENT); } return fieldDiff; } return null; }
9. Each class shall have independent functions as far as possible, reflect a single responsibility, and make the system reusable.
10. Use the combination method to solve the problem and reduce the coupling degree of the program.
11. Get used to unit testing to test whether the methods of each class meet the requirements after instantiation.
12. Program the interface instead of the implementation. Object composition is preferred over inheritance.