前言:公司有开发环境数据库,生产环境数据库。小伙伴在开发环境更换了数据库字段,导致上线到生产环境时数据库字段不一致,所有写啦一个数据库对比工具分享给大家!!

public static final String SQLForGetTables = "select * from pg_tables WHERE schemaname='public'";
public static int tableAccount = 0;
public static int columnAccount = 0;
public static String tableMessage1 ;
public static String columnMessage ;
public static String errTable;
public static String db1 = "dmp";
public static String db2 = "dmp";
public static String IP1 = "0.0.0.14:30757";
public static String IP2 = "0.0.0.45:31150";
public static void main(String[] args) throws Exception {
    //开发环境
    Connection con1 = getConnection(IP1, db1, "postgres", "hello1234");
    //生产环境
    Connection con2 = getConnection(IP2, db2, "postgres", "hello1234");
    // 查询出字段名称
    List list = getInfos(con1, SQLForGetTables);
    List list2 = getInfos(con2, SQLForGetTables);
    System.out.println("将"+IP1+"的数据库"+db1+"与"+IP2+"数据库"+db2+"进行比较");
    tableMessage1="数据库"+db2+"缺少的表为: ";
    String res = checkTables(list, list2, con1, con2);
    System.out.println(tableMessage1);
    System.out.println("-------------------------比较完成");
    System.out.println();
    System.out.println("将"+IP2+"的数据库"+db2+"与"+IP1+"与数据库"+db1+"进行比较");
    tableMessage1="数据库"+db1+"缺少的表为:";
    res = checkTables(list2, list, con2, con1);
    System.out.println(tableMessage1);
    System.out.println("-------------------------比较完成");
    System.out.println("这两个数据库中 有"+tableAccount+"个表不相同");
    System.out.println("这两个数据库中 有"+columnAccount+"个字段不相同");
private static Connection getConnection(String ip, String dbName, String user, String pwd) throws ClassNotFoundException {
    Connection con = null;
    //String url1 = "jdbc:postgresql://10.70.21.14:30757/dmp";
    String url1 = "jdbc:postgresql://"+ip+"/"+dbName+"";
    Class.forName("org.postgresql.Driver");
    try {
        con = DriverManager.getConnection(url1, user, pwd);//如何用一个参数连接
    } catch (SQLException e) {
        System.out.println("开发环境数据库连接失败:" + e.getMessage());
    return con;
// 比较两个LIST中的数据是否一致
@SuppressWarnings("rawtypes")
private static String checkTables(List list, List list2, Connection con1, Connection con2) {
    // 先将数据库1的数据与2比较
    int table = 0;
    int colum = 0;
    for (Object object : list) {
        table = 0;
        for (Object object2 : list2) {
            if (object.equals(object2)) {
                colum = checkDetail(object, object2, con1, con2);
                table = 1;
                continue;
        if (table == 0) {
            errTable = getName(object);
            tableAccount++;
            tableMessage1 = tableMessage1 + getName(object) + "; ";
            table = 1;
            continue;
    if (table == 0 && colum == 0) {
        return "两个数据库中表和字段一致";
    if (table == 0 && colum == 1) {
        return "两个数据库中表一致 字段不一致";
    if (table == 1 && colum == 0) {
        return "两个数据库中表不一致 字段一致";
    } else
        return "两个数据库中表不一致 字段也不一致";
// 比较两个表字段是否一致
@SuppressWarnings("rawtypes")
private static int checkDetail(Object object, Object object2, Connection con1, Connection con2) {
    // 获得表的名字
    String table = getName(object);
    errTable = table;
   String sql = "SELECT A.attname FROM pg_catalog.pg_attribute A WHERE 1 = 1 AND A.attrelid = ( SELECT oid FROM pg_class WHERE relname = '" + table + "' ) AND A.attnum > 0 AND NOT A.attisdropped ORDER BY A.attnum";
    // 查询出字段名称
    List list = getInfos(con1, sql);
    List list2 = getInfos(con2, sql);
    return checkColunm(list, list2);
// 检查表中的字段是否一致
@SuppressWarnings("rawtypes")
private static int checkColunm(List list, List list2) {
    int res = 0;
    for (Object object : list) {
        int result = 0;
        for (Object object2 : list2) {
        // 如果这个字段在全部数据都匹配不到 则证明这个字段不匹配
            if (object.equals(object2)) {
                result = 1;
                break;
        if (result == 0) {
            columnAccount++;
            System.out.println("请注意 !表" + errTable + "中的" + getName(object) + "字段在后者数据库中没有");
            res = 1;
    return res;
// 根据OBJECT获得name的值
private static String getName(Object object) {
    Map map = JSONObject.parseObject(JSONObject.toJSONString(object), Map.class);
    return map.get("tablename")==null?map.get("attname")==null?"":map.get("attname").toString():map.get("tablename").toString();
// 查询数据库里面的表信息
@SuppressWarnings({"rawtypes", "unchecked"})
private static List getInfos(Connection con1, String sql) {
    Statement stmt;
    List list = new ArrayList();
    try {
        stmt = con1.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        ResultSetMetaData md = rs.getMetaData();
        int columnCount = md.getColumnCount();
        while (rs.next()) {
            Map map = new HashMap();
            for (int i = 1; i <= columnCount; i++) {
                map.put(md.getColumnName(i), rs.getObject(i));
            list.add(map);
    } catch (SQLException e) {
        System.out.println("查询数据库里面的表信息失败:" + e.getMessage());
        e.printStackTrace();
    return list;
				
pgcompare 适用于Linux,Mac OS X和Windows的Postgres数据库比较。 PG Compare将允许您比较两个Postgres数据库。 该应用程序不编写更改脚本,而是显示两个数据库模式之间的更改。 Tables和Functions是当前唯一被比较的架构对象。 该应用程序的外壳基于项目。 UI是使用呈现的。
缓存缓存对于数据库的系统性能有着重要意义。本文虽以Postgres为例,但也可对应到其他数据库系统。不同的计算机部件有着不同的运行速度。人类在理解数字的规模上面,与计算机有着极大的差距。对此,通过下面这张表格(截取自《文字间的无限空间》TheInfiniteSpaceBetweenWords),会有一个更直观的认识。表中数据是从人类角度加以估算。在数据库系统中,技术人员最关注的往往是硬盘的I/O问题。与新的固态硬盘(SSD)相比,磁盘在随机I/O方面的性能较差。大多数OLTP的工作负载都属于随机I/O,因此获取硬盘中信息时,速度就会极其缓慢。为了克服这一劣势,Postgres利用随机存取存储器
复制工具 (安装、配置) 一般工具 (磁盘使用情况、冗余索引、搜索元数据) MySQL Utilities是一系列的命令行工具以及python库更容易完成管理的任务。库是用Python语言写的,这就意味着不需要安装其他任何工具和库。当前是基于Python2.6版本设计的,不支持Python3.1版本。 MySQL Uti
作者:阎书利 pgquarrel是一个PostgreSQL数据库数据库结构(DDL)比对工具。它会对比两个数据库源,并输出一个表示DDL差异的文件。 如果将输出文件运行到目标数据库中,它将具有与源数据库相同的结构。 主要使用场景是将数据库更改部署到测试或生产环境。 pgquarrel不依赖于另一个工具(如pg_dump),而是直接连接到 PostgreSQL 服务器,从目录中获取元数据,比较对象并输出将目标数据库转换为源数据库所需的命令。它拥有过滤器选项:所以,可以比较部分对象。 它可以适用于不同的Pos
我们在实际开发的过程中,通常会有开发环境、测试环境、生产环境等。 在这些环境中,一般会有各自对应的数据库,由于每次新需求都是在测试环境中进行的测试,所以就会导致不同环境的数据库结构有不同。 当新一版本的功能在测试环境测好后,需要将新功能更新至生产环境,此时,生产环境数据库结构就需要再一次和测试环境数据库结构保持一致,才能保证新功能正常使用。 【数据库比较】 当我们想知道两个数据库的有哪些变化时候,如果每张表,每个字段的去比较,当在变化很大的时候,这将会是一个很不友好的体验,不但耗时耗
pgdiff-PostgreSQL模式差异 pgdiff比较两个PostgreSQL 9数据库之间的模式,并生成alter语句以针对第二个数据库手动运行以使其匹配。 提供的pgdiff.sh脚本有助于自动化该过程。 pgdiff的工作是透明的,因此它永远不会直接修改数据库。 在对数据库运行生成SQL之前,您自己一个人负责验证生成SQL。 继续,看看生成了什么SQL。 pgdiff被编写为易于扩展和提高diff的准确性。 下载1.0 beta 1 pgdiff [options] <schemaType> (下面列出了选项和<schemaType>) 运行不同的架构类型似乎是一