对比_对比柱状图 - CSDN
精华内容
参与话题
  • 对比Excel,轻松学习Python数据分析》这本书已经读完了,我们做一个目录汇总,以后就可以在目录下查阅各章节相关内容了。 第一章、 第二章、 第三章、 第四章、 第五章、 第六章、 第七章、 第八章、 ...

    《对比Excel,轻松学习Python数据分析》这本书已经读完了,我们做一个目录汇总,以后就可以在目录下查阅各章节相关内容了。

    第一章、数据分析基础,知识点
    第二章、知识点:python中map()函数的用法讲解
    第三章、知识点:pandas数据结构
    第四章 、准备食材——获取数据源,知识点
    第五章、淘米洗菜——数据预处理,知识点
    第六章、菜品挑选——数据选择,知识点
    第七章 、切配菜品-数值操作,知识点
    第八章、开始烹调——数据运算,知识点
    第九章、炒菜计时器——时间序列,知识点
    第十章 、菜品分类——数据分组/数据透视表,知识点
    第十一章、 水果摆盘——多表拼接,知识点
    第十二章、 盛菜装盘——结果导出,知识点
    第十三章、菜品摆放——数据可视化,知识点
    第十四章、典型数据分析案例,知识点
    第十五章、NumPy数组,知识点
    特殊数组
    随机数组

    更新时间:2019年11月10日;写于:上海浦东图书馆

    喜欢可以关注【小猪课堂】公众号了解更多内容

    展开全文
  • git 对比两个分支差异

    万次阅读 多人点赞 2018-08-11 11:20:07
    比如我们有 2 个分支:master, dev,现在想查看这两个 branch 的区别,有以下几种方式:1.查看 dev 有,而 master 中没有的:git log dev ^master 同理查看 master 中有,而 dev 中没有的内容:git log master ^dev2...

    比如我们有 2 个分支:master, dev,现在想查看这两个 branch 的区别,有以下几种方式:

    1.查看 dev 有,而 master 中没有的:

    git log dev ^master 

    同理查看 master 中有,而 dev 中没有的内容:

    git log master ^dev

    这里写图片描述

    2.查看 dev 中比 master 中多提交了哪些内容:

    git log master..dev

    注意,列出来的是两个点后边(此处即dev)多提交的内容。同理,想知道 master 比 dev 多提交了什么:

    git log dev..master

    这里写图片描述

    3.不知道谁提交的多谁提交的少,单纯想知道有什么不一样:

    git log dev...master

    这里写图片描述

    4.在上述情况下,再显示出每个提交是在哪个分支上:

    git log --left-right dev...master

    这里写图片描述

    注意 commit 后面的箭头,根据我们在 –left-right dev…master 的顺序,左箭头 < 表示是 dev 的,右箭头 > 表示是 master的。

    截图中表示这三个提交都是在 master 分支上的

    感谢

    http://blog.csdn.net/hongchangfirst/article/details/45368605


    欢迎扫描关注我的微信公众号,不定时更新我的成长及思考文章~

    这里写图片描述

    展开全文
  • 怎么对比2个数据库的差异

    千次阅读 2020-09-14 17:19:06
    今天接到一个任务,测试库和开发库不同步,领导让对比2个库的差异,对比原则表名、字段名、字段属性、字段长度、是否为空,刚接手任务,通过查询USER_TAB_COLUMNS表查询出测试库的表字段属性,之后在开发库新建一个...

              今天接到一个任务,测试库和开发库不同步,领导让对比2个库的差异,对比原则表名、字段名、字段属性、字段长度、是否为空,刚接手任务,通过查询USER_TAB_COLUMNS表查询出测试库的表字段属性,之后在开发库新建一个表,把数据导入,之后通过为左右连接为null判断是否存在,一查右4000来条数据,之后要一条一条的比较,这根本就做不了,之后想到了写程序达到效果,思路:

     demo路径:http://download.csdn.net/download/xionglangs/10224457

     1、分别查询到2个库的表名,表子段属性,分别存入MAP中(查询时最好按照表名排序)。

    2、第二步,把一个库名做为key,表名做value,遍历它,如果另外一个map根据key查询不到值,表示此表没有在另外一个库中。

    3、之后比较表子段属性,用表名和字段名做key,其余5个属性做值,传入2中查询到的list,过滤key在2中的,就表示2库中都存在表,但字段维度不同。

    4、重复上诉步骤,把两个库替换。

    代码为:

    packagecom.sunline.util;

     

    import java.io.File;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * @author 熊浪
     * @Email xiongl@sunline.cn
     * @Time 2018年1月25日 @此类的作用:
     */
    public class DatabaseUtil {
        private final static Logger logger = LoggerFactory.getLogger(DatabaseUtil.class);
    
        private static final String DRIVER = "oracle.jdbc.OracleDriver";
        private static final String URL1 = "jdbc:oracle:thin:@10.22.20.12:1521/UATDEMODB";
        private static final String URL2 = "jdbc:oracle:thin:@10.24.0.234:1521/DEVSITDB";
        private static final String USERNAME1 = "uat_sungl";
        private static final String PASSWORD1 = "uat_sungl";
        private static final String USERNAME2 = "sit_sungl";
        private static final String PASSWORD2 = "sit_sungl";
        private static final String TABLE_INFO = "SELECT DISTINCT TABLE_NAME FROM USER_TABLES";
        private static final String TABLE_NAME = "SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE,DATA_LENGTH,NULLABLE FROM USER_TAB_COLUMNS";
        private static final String SQL = "SELECT * FROM ";// 数据库操作
    
        static {
            try {
                Class.forName(DRIVER);
            } catch (ClassNotFoundException e) {
                logger.error("can not load jdbc driver", e);
            }
        }
    
        /**
         * 获取数据库连接
         *
         * @return
         */
        public static Connection getConnection(String url, String userName, String password) {
            Connection conn = null;
            try {
                conn = DriverManager.getConnection(url, userName, password);
            } catch (SQLException e) {
                logger.error("get connection failure", e);
            }
            return conn;
        }
    
        /**
         * 关闭数据库连接
         *
         * @param conn
         */
        public static void closeConnection(Connection conn) {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    logger.error("close connection failure", e);
                }
            }
        }
    
        /**
         * 获取数据库下的所有表名
         */
        public static Map<String, String> getTableInfos(String url, String userName, String password) {
            Map<String, String> tableNames = new HashMap<String, String>();
            Connection conn = getConnection(url, userName, password);
            PreparedStatement pst = null;
            ResultSet rs = null;
            try {
                pst = conn.prepareStatement(TABLE_NAME);
                rs = pst.executeQuery();
                while (rs.next()) {
                    tableNames.put(rs.getString(1) + "=" + rs.getString(2), rs.getString(1) + "=" + rs.getString(2) + "=" + rs.getString(3) + "=" + rs.getString(4) + "=" + rs.getString(5) + "=" + rs.getString(1));
                }
            } catch (SQLException e) {
                logger.error("getTableNames failure", e);
            } finally {
                try {
                    rs.close();
                    closeConnection(conn);
                } catch (SQLException e) {
                    logger.error("close ResultSet failure", e);
                }
            }
            return tableNames;
        }
    
        public static Map<String, String> getTableNames(String url, String userName, String password) {
            Map<String, String> tableNames = new HashMap<String, String>();
            Connection conn = getConnection(url, userName, password);
            PreparedStatement pst = null;
            ResultSet rs = null;
            try {
                pst = conn.prepareStatement(TABLE_INFO);
                rs = pst.executeQuery();
                while (rs.next()) {
                    tableNames.put(rs.getString(1), rs.getString(1));
                }
            } catch (SQLException e) {
                logger.error("getTableNames failure", e);
            } finally {
                try {
                    rs.close();
                    closeConnection(conn);
                } catch (SQLException e) {
                    logger.error("close ResultSet failure", e);
                }
            }
            return tableNames;
        }
    
        /**
         * 获取表中所有字段名称
         *
         * @param tableName 表名
         * @return
         */
        public static List<String> getColumnNames(String tableName, String url, String userName, String password) {
            List<String> columnNames = new ArrayList<>();
            // 与数据库的连接
            Connection conn = getConnection(url, userName, password);
            PreparedStatement pStemt = null;
            String tableSql = SQL + tableName;
            try {
                pStemt = conn.prepareStatement(tableSql);
                // 结果集元数据
                ResultSetMetaData rsmd = pStemt.getMetaData();
                // 表列数
                int size = rsmd.getColumnCount();
                for (int i = 0; i < size; i++) {
                    columnNames.add(rsmd.getColumnName(i + 1));
                }
            } catch (SQLException e) {
                logger.error("getColumnNames failure", e);
            } finally {
                if (pStemt != null) {
                    try {
                        pStemt.close();
                        closeConnection(conn);
                    } catch (SQLException e) {
                        logger.error("getColumnNames close pstem and connection failure", e);
                    }
                }
            }
            return columnNames;
        }
    
        /**
         * 获取表中所有字段类型
         *
         * @param tableName
         * @return
         */
        public static List<String> getColumnTypes(String tableName, String url, String userName, String password) {
            List<String> columnTypes = new ArrayList<>();
            // 与数据库的连接
            Connection conn = getConnection(url, userName, password);
            PreparedStatement pStemt = null;
            String tableSql = SQL + tableName;
            try {
                pStemt = conn.prepareStatement(tableSql);
                // 结果集元数据
                ResultSetMetaData rsmd = pStemt.getMetaData();
                // 表列数
                int size = rsmd.getColumnCount();
                for (int i = 0; i < size; i++) {
                    columnTypes.add(rsmd.getColumnTypeName(i + 1));
                }
                Arrays.sort(columnTypes.toArray());
            } catch (SQLException e) {
                logger.error("getColumnTypes failure", e);
            } finally {
                if (pStemt != null) {
                    try {
                        pStemt.close();
                        closeConnection(conn);
                    } catch (SQLException e) {
                        logger.error("getColumnTypes close pstem and connection failure", e);
                    }
                }
            }
            return columnTypes;
        }
    
        public static List<List<String>> selectTableInfo(Map<String, String> uat, Map<String, String> sit) {
            Set<Entry<String, String>> uats = uat.entrySet();
            Iterator<Entry<String, String>> it = uats.iterator();
            Entry<String, String> infos = null;
            String uatInfo = "", sitInfo = "";
            List<List<String>> list = new ArrayList<List<String>>();
            String[] uatArray = null, sitArray = null;
            while (it.hasNext()) {
                infos = it.next();
                uatInfo = infos.getValue();
                sitInfo = sit.get(infos.getKey());
                if (!uatInfo.equals(sitInfo)) {
                    List<String> isDiffent = new ArrayList<String>();
                    uatArray = uatInfo.split("=");
                    for (int i = 0; i < uatArray.length; i++) {
                        isDiffent.add(uatArray[i]);
                    }
                    if (sitInfo != null) {
                        sitArray = sitInfo.split("=");
                        for (int i = 0; i < sitArray.length; i++) {
                            isDiffent.add(sitArray[i]);
                        }
                    } else {
                        for (int i = 0; i < uatArray.length; i++) {
                            isDiffent.add("");
                        }
                    }
                    list.add(isDiffent);
                }
            }
            return list;
        }
    
        public static List<List<String>>selectTableInfo(Map<String, String> uat, Map<String, String> sit, String prefix) {
            Set<Entry<String, String>> uats = uat.entrySet();
            Iterator<Entry<String, String>> it = uats.iterator();
            Entry<String, String> infos = null;
            String uatInfo = "", sitInfo = "";
            List<List<String>> list = new ArrayList<List<String>>();
            String[] uatArray = null, sitArray = null;
            int len=0;
            while (it.hasNext()) {
                infos = it.next();
                uatInfo = infos.getValue();
                sitInfo = sit.get(infos.getKey());
                if (!uatInfo.equals(sitInfo)) {
                    uatArray = uatInfo.split("=");
                    if (prefix != null && prefix.contains(uatArray[uatArray.length - 1])) {
                        continue;
                    }
                    List<String> isDiffent = new ArrayList<String>();
                    if(prefix!=null)
                        len=uatArray.length-1;
                    else
                        len=uatArray.length;
                    for (int i = 0; i < len; i++) {
                        isDiffent.add(uatArray[i]);
                    }
                    if (sitInfo != null) {
                        sitArray = sitInfo.split("=");
                        for (int i = 0; i < len; i++) {
                            isDiffent.add(sitArray[i]);
                        }
                    } else {
                        for (int i = 0; i < len; i++) {
                            isDiffent.add("");
                        }
                    }
                    list.add(isDiffent);
                }
            }
            return list;
        }
    
        public static void main(String[] args) {
            Map<String, String> uatTable = getTableNames(URL1, USERNAME1, PASSWORD1);
            Map<String, String> sitTable = getTableNames(URL2, USERNAME2, PASSWORD2);
            Map<String, String> uatInfos = getTableInfos(URL1, USERNAME1, PASSWORD1);
            Map<String, String> sitInfos = getTableInfos(URL2, USERNAME2, PASSWORD2);
            String[] title = {"表名", "字段名", "字段类型", "字段长度", "是否为空", "表名", "字段名", "字段类型", "字段长度", "是否为空"};
            String[] infos = {"表名", "字段名", "字段类型", "字段长度", "是否为空", "表名", "字段名", "字段类型", "字段长度", "是否为空"};
            List<List<String>> uatTables = selectTableInfo(uatTable, sitTable, null);
            List<List<String>> infoTables = selectTableInfo(sitTable, uatTable, null);
            StringBuffer sbOne = new StringBuffer();
            StringBuffer sbTwo = new StringBuffer();
            for (List<String> list:uatTables)
                sbOne.append(list.get(0)+",");
            for (List<String> list:infoTables)
                sbTwo.append(list.get(0)+",");
            ExcelManage.writeInfoToExcel("UAT与SIT表名比较,前面现实UAT", "D:" + File.separator + "长亮", "UAT-SIT_TABLE", "xls", title, uatTables, TableInfoBean.class);
            ExcelManage.writeInfoToExcel("UAT与UAT字段名比较,前面现实UAT", "D:" + File.separator + "长亮", "UAT-SIT_CLOUMN", "xls", infos, selectTableInfo(uatInfos, sitInfos, sbOne.toString()), SujuInfoBean.class);
            ExcelManage.writeInfoToExcel("SIT与UAT表名比较,前面现实SIT", "D:" + File.separator + "长亮", "SIT-UAT_TABLE", "xls", title, infoTables, TableInfoBean.class);
            ExcelManage.writeInfoToExcel("SIT与UAT字段名比较,前面现实SIT", "D:" + File.separator + "长亮", "SIT-UAT_CLOUMN", "xls", infos, selectTableInfo(sitInfos, uatInfos, sbTwo.toString()), SujuInfoBean.class);
        }
    }
    
    package com.sunline.util;
    
    /**
     * @author 熊浪
     * @Email xiongl@sunline.cn
     * @Time 2018/1/25
     * @此类的作用:
     */
    public class TableInfoBean {
        private String tableName;
        public String getTableName() {
            return tableName;
        }
        public void setTableName(String tableName) {
            this.tableName = tableName;
        }
    }
    
    package com.sunline.util;
    
    /**
     * @author 熊浪
     * @Email xiongl@sunline.cn
     * @Time 2018年1月25日
     * @此类的作用:
     */
    public class SujuInfoBean {
        private String tableNameOne;
        private String cloumnOne;
        private String typeOne;
        private String cloumnLengthOne;
        private String isOrNullOne;
        private String tableNameTwo;
        private String cloumnTwo;
        private String typeTwo;
        private String cloumnLengthTwo;
        private String isOrNullTwo;
    
        public String getTableNameOne() {
            return tableNameOne;
        }
    
        public void setTableNameOne(String tableNameOne) {
            this.tableNameOne = tableNameOne;
        }
    
        public String getCloumnOne() {
            return cloumnOne;
        }
    
        public void setCloumnOne(String cloumnOne) {
            this.cloumnOne = cloumnOne;
        }
    
        public String getTypeOne() {
            return typeOne;
        }
    
        public void setTypeOne(String typeOne) {
            this.typeOne = typeOne;
        }
    
        public String getCloumnLengthOne() {
            return cloumnLengthOne;
        }
    
        public void setCloumnLengthOne(String cloumnLengthOne) {
            this.cloumnLengthOne = cloumnLengthOne;
        }
    
        public String getIsOrNullOne() {
            return isOrNullOne;
        }
    
        public void setIsOrNullOne(String isOrNullOne) {
            this.isOrNullOne = isOrNullOne;
        }
    
        public String getTableNameTwo() {
            return tableNameTwo;
        }
    
        public void setTableNameTwo(String tableNameTwo) {
            this.tableNameTwo = tableNameTwo;
        }
    
        public String getCloumnTwo() {
            return cloumnTwo;
        }
    
        public void setCloumnTwo(String cloumnTwo) {
            this.cloumnTwo = cloumnTwo;
        }
    
        public String getTypeTwo() {
            return typeTwo;
        }
    
        public void setTypeTwo(String typeTwo) {
            this.typeTwo = typeTwo;
        }
    
        public String getCloumnLengthTwo() {
            return cloumnLengthTwo;
        }
    
        public void setCloumnLengthTwo(String cloumnLengthTwo) {
            this.cloumnLengthTwo = cloumnLengthTwo;
        }
    
        public String getIsOrNullTwo() {
            return isOrNullTwo;
        }
    
        public void setIsOrNullTwo(String isOrNullTwo) {
            this.isOrNullTwo = isOrNullTwo;
        }
    
    }
    
    package com.sunline.util;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    /**
     * @author 熊浪
     * @Email xiongl@sunline.cn
     * @Time 2018年1月25日 @此类的作用:
     */
    public class ExcelManage {
       public static boolean writeInfoToExcel(String fileTitle, String path, String fileName, String fileType, String[] title, List<List<String>> list, Class<?> clazz) {
          boolean flag = false;
          try {
             writer(fileTitle, path, fileName, fileType, insertInfoToBean(list, clazz), title);
             flag = true;
          } catch (Exception e) {
             e.printStackTrace();
          }
          return flag;
       }
    
       private static List<Object> insertInfoToBean(List<List<String>> list, Class<?> clazz) throws Exception {
          List<Object> objs = new ArrayList<Object>();
          boolean flag = false;
          Field[] fields = clazz.getDeclaredFields();
          for (int i = 0, len = list.size(); i < len; i++) {
             Object obj = clazz.newInstance();
             for (int j = 0; j < fields.length; j++) {
                flag = fields[j].isAccessible();
                fields[j].setAccessible(true);
                try {
                   fields[j].set(obj, list.get(i).get(j));
                   fields[j].setAccessible(flag);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                   e.printStackTrace();
                }
             }
             objs.add(obj);
          }
          return objs;
       }
    
       private static void writer(String fileTitle, String path, String fileName, String fileType, List<Object> list, String titleRow[]) throws Exception {
          Workbook wb = null;
          String excelPath = path + File.separator + fileName + "." + fileType;
          File file = new File(excelPath);
          Sheet sheet = null;
          // 创建工作文档对象
          if (!file.exists()) {
             if (fileType.equals("xls")) {
                wb = new HSSFWorkbook();
             } else if (fileType.equals("xlsx")) {
                wb = new XSSFWorkbook();
             } else {
                throw new Exception("文件格式不正确");
             }
             // 创建sheet对象
             sheet = (Sheet) wb.createSheet("sheet1");
             OutputStream outputStream = new FileOutputStream(excelPath);
             wb.write(outputStream);
             outputStream.flush();
             outputStream.close();
          } else {
             if (fileType.equals("xls")) {
                wb = new HSSFWorkbook();
             } else if (fileType.equals("xlsx")) {
                wb = new XSSFWorkbook();
             } else {
                throw new Exception("文件格式不正确");
             }
          }
          // 创建sheet对象
          if (sheet == null) {
             sheet = (Sheet) wb.createSheet("sheet1");
          }
          // 添加表头
          Row row = sheet.createRow(0);
          Cell cell = row.createCell(0);
          row.setHeight((short) 540);
          cell.setCellValue(fileTitle); // 创建第一行
          CellStyle style = wb.createCellStyle(); // 样式对象
          // 设置单元格的背景颜色为淡蓝色
          style.setFillForegroundColor(HSSFColor.PALE_BLUE.index);
          style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);// 垂直
          style.setAlignment(CellStyle.ALIGN_CENTER);// 水平
          style.setWrapText(true);// 指定当单元格内容显示不下时自动换行
          cell.setCellStyle(style); // 样式,居中
          Font font = wb.createFont();
          font.setBoldweight(Font.BOLDWEIGHT_BOLD);
          font.setFontName("宋体");
          font.setFontHeight((short) 280);
          style.setFont(font);
          // 单元格合并
          // 四个参数分别是:起始行,起始列,结束行,结束列
          sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 7));
          sheet.autoSizeColumn(5200);
          row = sheet.createRow(1); // 创建第二行
          for (int i = 0; i < titleRow.length; i++) {
             cell = row.createCell(i);
             cell.setCellValue(titleRow[i]);
             cell.setCellStyle(style); // 样式,居中
             sheet.setColumnWidth(i, 20 * 256);
          }
          row.setHeight((short) 540);
          Field[] fields = null;
          if (!list.isEmpty())
             fields = list.get(0).getClass().getDeclaredFields();
          // 循环写入行数据
          boolean flag = false;
          for (int i = 0; i < list.size(); i++) {
             row = (Row) sheet.createRow(i + 2);
             row.setHeight((short) 500);
             for (int j = 0; j < fields.length; j++) {
                flag = fields[j].isAccessible();
                fields[j].setAccessible(true);
                try {
                   row.createCell(j).setCellValue("" + fields[j].get(list.get(i)));
                } catch (IllegalArgumentException | IllegalAccessException e) {
                   throw new Exception(e.getMessage());
                }
                fields[j].setAccessible(flag);
             }
          }
          // 创建文件流
          OutputStream stream = new FileOutputStream(excelPath);
          // 写入数据
          wb.write(stream);
          // 关闭文件流
          stream.close();
       }
    }
    

     

     

     

    
     
    展开全文
  • 开源OLAP引擎对比

    千次阅读 2019-07-28 15:59:50
    文章目录开源OLAP引擎对比OLAP简介分布式OLAP引擎分类及对比基于MPP架构的ROLAP引擎预计算引擎架构的MOLAP搜索引擎架构纯列存OLAP基于内存的SnappyData对比 开源OLAP引擎对比 OLAP简介 OLAP(On-Line Analytical ...

    开源OLAP引擎对比

    OLAP简介

    1. OLAP(On-Line Analytical Processing),即联机分析处理,其主要的功能在于方便大规模数据分析及统计计算,对决策提供参考和支持
    2. 特点
    • 数据量大
    • 高速响应
    • 灵活交互
    • 多维分析

    在这里插入图片描述

    1. 分类
    • 存储类型分类
    • ROLAP(RelationalOLAP)
    • MOLAP(MultidimensionalOLAP)
    • HOLAP(HybridOLAP)
    • 处理类型分类
    • MPP架构
    • 搜索引擎架构
    • 预处理架构
    1. 开源OLAP解决方案
    • Presto、SparkSQL、Impala以及SnappyData等MPP架构和ROLAP的引擎
    • Druid和Kylin等预处理架构和MOLAP的引擎
    • ES这种搜索引擎架构
    • ClickHouse以及IndexR这种列式数据库

    分布式OLAP引擎分类及对比

    1. 数据规模、查询性能、灵活性、易用性、处理方式以及实时性进行对比

    基于MPP架构的ROLAP引擎

    1. 代表:Presto、Impala以及Spark SQL等利用关系模型来处理OLAP查询,通过并发提高查询性能
    2. 优点
    • 支持的数据规模大(非存储引擎)
    • 灵活性高,随意查询数据
    • 易用性强,支持标准SQL以及多表join和窗口函数
    • 处理方式简单,无需预处理,全部后处理,没有冗余数据
    1. 缺点
    • 性能较差,当查询复杂度高且数据量大时,可能分钟级别的响应。同时其不是存储引擎,因此没有本地存储,当join时shuffle开销大,性能差
    • 举例:SparkSql为例子,其只是哥计算引擎,导致需要从外部加载数据,从而数据的实时性得不到保证;多表join的时候性能也很难得到秒级的响应
    • 开源社区出现了一种依托于Spark SQL的AP引擎,如:TiSpark(TiKV作为存储)、SnappyData
    • 实时性较差,不支持数据的实时导入,偏离线处理

    预计算引擎架构的MOLAP

    1. 代表
    • Kylin是完全预计算引擎,通过枚举所有维度的组合,建立各种Cube进行提前聚合,以HBase为基础的OLAP引擎
    • Druid则是轻量级的提前聚合(roll-up),同时根据倒排索引以及bitmap提高查询效率的时间序列数据和存储引擎
    1. 优点
    • Kylin
    • 支持数据规模超大(HBase)
    • 易用性强,支持标准SQL
    • 性能很高,查询速度很快
    • Druid
    • 支持的数据规模大(本地存储+DeepStorage–HDFS)
    • 性能高,列存压缩,预聚合加上倒排索引以及位图索引,秒级查询
    • 实时性高,可以通过kafka实时导入数据
    1. 缺点
    • Kylin
    • 灵活性较弱不支持adhoc查询;且没有二级索引,过滤时性能一般;不支持join以及对数据的更新
    • 处理方式复杂,需要定义Cube预计算;当维度超过20个时,存储可能会爆炸式增长;且无法查询明细数据了;维护复杂
    • 实时性很差,很多时候只能查询前一天或几个小时前的数据
    • Druid
    • 灵活性适中,虽然维度之间随意组合,但不支持adhoc查询,不能自由组合查询,且丢失了明细数据
    • 易用性较差,不支持join,不支持更新,sql支持很弱(有些插件类似于pinot的PQL语言),只能JSON格式查询;对于去重操作不能精准去重
    • 处理方式复杂,需要流处理引擎将数据join成宽表,维护相对复杂;对内存要求较高
    1. 场景
    • Kylin:适合对实时数据需求不高,但响应时间较高的查询,且维度较多,需求较为固定的特定查询;而不适合实时性要求高的adhoc类查询
    • Druid:数据量大,对实时性要求高且响应时间短,以及维度较少且需求固定的简单聚合类查询(sum,count,TopN),多以storm和flink组合进行预处理;而不适合需要join、update和支持SQL和窗口函数等复杂的adhoc查询;不适合用于SQL复杂数据分析的场景

    搜索引擎架构

    1. 代表
    • ES是典型的搜索引擎类的架构系统,在入库时将数据转换为倒排索引,采用Scatter-Gather计算模型提高查询性能。- 对于搜索类的查询效果较好,但当数据量较大时,对于Scan类和聚合类为主的查询性能较低
    1. 优点
    • 性能较高,支持倒排索引和各种过滤后的聚合查询
    • 实时性强,在文档上建立完索引后,立刻可以查询
    • 处理方式简单,无需预处理
    1. 缺点
    • 支持的数据规模较小,高并发不理想
    • 灵活性差,不支持复杂的adhoc查询
    • 易用性差不支持SQL;DSL成本高,且不能精准去重
    1. 场景
      -ES适合那种全文检索,且数据规模较少时过滤条件很多的聚合查询,并发度也不大的场景。
    • 同样,如果分析人员想用SQL分析,那么也不适合ES

    纯列存OLAP

    1. 代表
    • ClickHouse是个列存数据库,保存原始明细数据,通过MergeTree使得数据存储本地化来提高性能
    • 是个单机版超高性能的数据库
    1. 优点
    • 性能高,列存压缩比高,通过索引实现秒级响应
    • 实时性强,支持kafka导入
    • 处理方式简单,无需预处理,保存明细数据
    1. 缺点
    • 数据规模一般
    • 灵活性差,不支持任意的adhoc查询,join的支持不好
    • 易用性较弱,SQL语法不标准,不支持窗口函数等;维护成本高
    1. 场景
    • 适合数据规模不大情况下的单机且单表的数据分析

    基于内存的SnappyData

    1. 代表
    • SnappyData是个计算与存储引擎全内存行列混合存储且完全不需预处理,支持SQL与Spark SQL
    • 兼顾MPP的特点且colocate特性使得数据本地化,支持join、列表的update以及窗口函数等任意的adhoc查询
    1. 优点
    • 性能高,列存压缩+全内存,数据状态共享,秒级查询
    • 实时性强,支持kafka的stream table以及实时导入
    • 处理方式简单,无需预处理,保存明细数据,数据本地存储
    • 灵活性高,是个sql数据库,支持任意字段的查询、update以及窗口函数和复杂的adhoc查询
    • 易用性强,支持标准SQL和Spark SQL,精准去重,支持各种分许函数
    1. 缺点
    • 数据规模中等,由于全内存导致成本较高,且需要关注GC问题
    • 维护成本高
    1. 场景
    • SnappyData适合那种数据规模中等(PB以下),需求变化较多,实时性要求较高、响应时间较短复杂的窗口函数类查询;同时适合查询明细数据以及探索式的adhoc查询
    • 如果数据规模不大,且希望找到一种简单易用且实时性要求高的多维OLAP引擎,最重要的是可供分析人员使用的SQL的引擎,那么SnappyData比较适合。前提是需要在成本与效率之间做个平衡,SQL固然能提高开发效率,但内存较大的服务器成本也确实相对较高

    对比

    在这里插入图片描述

    指标 Spark SQL Druid Kylin SnappyData
    数据规模 超大 超大
    响应时间
    并发
    实时性
    SQL能力
    去重能力 精准 近似 近似 精准
    Join能力
    Update能力
    存储能力 sharded nothing sharded nothing sharded nothing
    成本
    展开全文
  • 自动格式化,对比JSON不同处,高亮显示。 另外推荐一个文本比较器:https://www.sojson.com/gongju/textdiff.html JSON比较,有的用户反馈下面的这个比较还比较好用点,看每个人自己怎么使用吧,有神马建议可以...
  • 这个软件兼容很多文件格式,但对java编译后的.class文件就不听话,出现乱码,无论你更换怎样的编码格式,还是乱码,这时你需要插件才能解决这个问题,插件下载也是有要求,对应版本要下载对应的插件,不然就回出现...
  • SSH和SSM对比总结

    万次阅读 多人点赞 2016-10-25 17:41:07
    当下流行的两种企业开发MVC开源框架,是我们Java程序猿必备知识能力。MVC,即模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务...
  • 容提要:文章详细介绍ps对比度的调整方法,并给出一幅缺乏对比度的问题图像来介绍。ps对比度调整包括使用ps自动对比度、色阶、曲线命令调整的原理和方法。  对比度是指一幅图像中,明暗区域中最亮的白色和最暗的...
  • 去年 6 月份写的博文《Yusuke Sugomori 的 C 语言 Deep Learning 程序解读》是囫囵吞枣地读完一个关于 DBN 算法的开源代码后的笔记,当时对其中涉及的算法原理基本不懂。近日再次学习 RBM,觉得有必要将其整理成笔记...
  • vscode实现文件对比

    万次阅读 2019-04-28 19:36:52
    打开文件目录,才能进行文件对比。 选中待比较文件1,右键--select for compare 再选中待比较文件2,右键--select for compare: 即可比较:
  • 用于图像去雾的优化对比度增强算法

    万次阅读 多人点赞 2020-04-17 03:21:47
    今天我们来介绍一篇由韩国学者所发表的研究论文《用于图像去雾的优化对比度增强算法》,作者提出一种基于四叉树划分的求解大气光估计的方法,同时提出了兼顾对比度和信息损失的图像去雾新思路,非常值得参考
  • 使用python实现图像对比度增强

    万次阅读 2018-05-25 22:15:08
    对单张图像进行图像对比度增强:from PIL import Image from PIL import ImageEnhance img = Image.open('./0h/FGF2.tif') img.show() #对比度增强 enh_con = ImageEnhance.Contrast(img) contrast = 1.5 img_...
  • 下载地址:http://www.scootersoftware.com/download.php
  • (1)对比度:一副图像中,各种不同颜色最亮处和最暗处之间的差别,差别越大对比度越高,这个跟分辨率没有多少关系,只跟最暗和最亮有关系,对比度越高一个图像给人的感觉就越刺眼,更加鲜亮,突出;越低则给人感觉...
  • 对比度是指相邻颜色的反差,(可以简单这么理解),调大对比度图像轮廓就会越分明,不过对比不明显的部分损失的就越多。 饱和度指色彩,调节饱和度色彩会发生变化,调的越大,图像颜色就越失真,调节饱和度只适合...
  • Sometimes,我们会有这样的需求,即:想对比出两个不同版本代码的区别。如何实现? 第 1 种:如果我们是从 SVN 检出的项目,并且想比较本地代码与从 SVN 检出时的代码相比都有那些区别,可以按如下步骤操作, 如上图...
  • 针对数据库 多表 多字段 多数据使用。...2.电脑运行sql服务,打开Navicat Premium,创建连接,创建数据库,将要对比的数据库 分别创建导入sql文件。 3. 对比后 红色显示缺少的表,蓝色显示是结构数据不行同的表
  • 导读对比分析在于看出基于相同数据标准下,由其他影响因素所导致的数据差异,而对比分析的目的在于找出差异后进一步挖掘差异背后的原因,从而找到优化的方法。来源:诸葛io数据教练...
  • http://docs.notepad-plus-plus.org/index.php/Plugin_Central#C
  • 你的mysql加索引了吗

    万次阅读 2020-01-13 11:39:21
    阿里云RDS增加索引优化11日前后对比 增加索引前后mysq CPU/内存利用率对比 增加索引前后mysq存储空间使用量(MB)使用对比 InnoDB Redo 写次数 增加索引前后InnoDB Row Operations对比 增加索引前后...
1 2 3 4 5 ... 20
收藏数 1,169,258
精华内容 467,703
关键字:

对比