【产品需求】

对所有元数据进行分析,匹配出表字段相似度达到阈值的向相似结构表关系数据。

网上没有搜到相关算法实现,只能自己动手了。

【算法实现】

简单点实现的话,可以轮询所有表,每张表都和其它表进行匹配相似度,不过这是人干的事?如果有1W张表岂不要查询1W × 9999次?

1、先统计出相同字段、表、表字段数量,其中相同字段对应的多个表和表字段数量通过行合并成字符串用逗号分隔,BXX:表信息、BZD:表字段信息,查询SQL脚本和查询结果如下:

SELECT
*
FROM (
SELECT BZD.ZDYWM, BZD.ZDZWM, BZD.ZDLX, count(1) AS "same", GROUP_CONCAT(BZD.B_ID) AS "bIds", GROUP_CONCAT(BXX.ZDSL) AS "zdsl"
FROM BZD LEFT JOIN BXX ON BZD.B_ID = BXX.ID
WHERE BXX.SFSC = 'N' AND BZD.SFSC = 'N'
GROUP BY BZD.ZDYWM, BZD.ZDZWM, BZD.ZDLX
) _ALL
WHERE SAME > 1

2、现在已经知道了相同字段和表之间的联系

我们来分析一下,统计出来的一条数据,代表某个字段在多个表同时存在,表和表之间构成了一次相同字段

后面我们只需要把所有数据通过算法计算一边,计算统计数据中表和表之间两两存在相同字段的数量,并和表本身的字段数量比较,达到相似结构表阈值的两张表即互为相似结构表

具体算法如下:

/**
* 相似结构表数据计算写入
* 实现思路:
* 1、group by字段信息表,查询存在重复的字段及表Id、表字段数量;
* 2、查询出的一条数据代表某一字段多个表都存在;
* 3、循环所有数据找出表和表之间存在相同字段的数量累加,数据结构如下;
* -------------------------------------------------------------
* 本表 本表字段数量 -> 可能存在相似结构的表1 相同字段数量
* 可能存在相似结构的表2 相同字段数量
* 可能存在相似结构的表3 相同字段数量
* 可能存在相似结构的表4 相同字段数量
* -------------------------------------------------------------
* 4、根据阈值计算符合相似结构表之间的关系;
*/
@Override
public void insert() { // 查询存在重复字段的表信息
// --------------------------------------------------------------------------------
// 字段英文名、字段中文名、字段类型、bId1,bId2,bId3,bId4、bzdsl1,bzdsl2,bzdsl3,bzdsl4
// --------------------------------------------------------------------------------
List<XsjgbzdxxDTO> xsjgbzdxxes = null;
try {
xsjgbzdxxes = xsjgbDao.selectColumnGroup();
} catch (Exception e) {
log.error("查询存在重复字段的表信息出错", e);
return ;
} // 非空效验
if (CollectionUtils.isEmpty(xsjgbzdxxes)) {
log.warn("没有查询到重复字段的表信息");
return ;
} // 统计相似结果表数据集合
List<Xsjgbxx> xsjgbxxes = null;
xsjgbxxes = new ArrayList<>(); // 同一字段多个表都存在的表Id
List<String> bIds = null;
// 同一字段多个表都存在的表字段数量
List<Integer> zdsl = null; Xsjgbxx b1, b2; // 每行数据都是一个字段多个表都存在的相同字段
for (XsjgbzdxxDTO xsjgbzdxx : xsjgbzdxxes) { // 非空效验
if (StringUtils.isEmpty(xsjgbzdxx.getBIds()) || StringUtils.isEmpty(xsjgbzdxx.getZdsl())) {
log.warn("表Id为空或表字段数量为空, xsjgbzdxx[{}]", JSONObject.toJSONString(xsjgbzdxx));
continue;
} // 获取所有表Id
bIds = Arrays.asList(xsjgbzdxx.getBIds().split(","));
// 获取所有表字段数量
zdsl = Arrays.asList(xsjgbzdxx.getZdsl().split(",")).stream().map(Integer::parseInt).collect(Collectors.toList()); // 相同字段多个表两两配对
for (int i=0 ; i<bIds.size() ; i++) { for (int j=(i+1) ; j<bIds.size() ; j++) { // 查找当前匹配的两张表的相似结构表信息对象
b1 = find(xsjgbxxes, bIds.get(i), zdsl.get(i));
b2 = find(xsjgbxxes, bIds.get(j), zdsl.get(j)); // 当前循环中的两个中互为疑似相似表
// 增加疑似相似表及相似字段数量
this.addColumnNum(b1, b2.getBId());
this.addColumnNum(b2, b1.getBId()); }
} } List<Xsjgb> xsjgbs = this.filter(xsjgbxxes); // 相似结构表数据入库
xsjgbDao.insertList(xsjgbs); } /**
* 根据表Id在相似表统计集合中查找对应的相似结构表信息
* @param xsjgbxxes
* @param bId
* @return
*/
private Xsjgbxx find(List<Xsjgbxx> xsjgbxxes, String bId, Integer zdsl) {
Xsjgbxx xsjgbxx = xsjgbxxes.stream().filter(item -> Objects.equals(item.getBId(), bId)).findFirst().orElse(null);
if (Objects.isNull(xsjgbxx)) {
xsjgbxx = new Xsjgbxx(bId, zdsl);
xsjgbxxes.add(xsjgbxx);
}
return xsjgbxx;
} /**
* 增加表对应的疑似相似结构表相似字段数量
* @param xsjgbxx
* @param xsbId
*/
private void addColumnNum(Xsjgbxx xsjgbxx, String xsbId) {
// 找到相似表信息
XsjgGxbxx xsjgGxbxx = xsjgbxx.getXsjgGxbxxes().stream().filter(item -> Objects.equals(item.getXsbId(), xsbId)).findFirst().orElse(null);
// 判断是否存在相似表信息
if (Objects.isNull(xsjgGxbxx)) {
// 记录新的相似表信息
xsjgbxx.getXsjgGxbxxes().add(new XsjgGxbxx(xsbId));
} else {
// 相似字段数量累加
xsjgGxbxx.increment();
}
} /**
* 根据统计出来的疑似相似结构表和相似度阈值过滤出相似结构表信息
* @param xsjgbxxes
* @return
*/
private List<Xsjgb> filter(List<Xsjgbxx> xsjgbxxes) { List<Xsjgb> xsjgbs = null;
xsjgbs = new ArrayList<>(); for (Xsjgbxx xsjgbxx : xsjgbxxes) { for (XsjgGxbxx xsjgGxbxx : xsjgbxx.getXsjgGxbxxes()) { // 相似表的相似字段数量除以本表的字段数量
// 大于相似度阈值的计入相似结构表
if (new BigDecimal(xsjgGxbxx.getXszdsl()).divide(new BigDecimal(xsjgbxx.getZdsl()), 20, BigDecimal.ROUND_HALF_UP).compareTo(XsjgbServiceImpl.DISTANCE) >= 0) {
xsjgbs.add(new Xsjgb(xsjgbxx.getBId(), xsjgGxbxx.getXsbId()));
} } } return xsjgbs; }
public class XsjgGxbxx implements Serializable {

    private static final long serialVersionUID = -8772273934672363080L;

    /**
* 可能存在相似结构的表Id
*/
private String xsbId; /**
* 相似字段数量
*/
private Integer xszdsl; public XsjgGxbxx(String xsbId) {
this.xsbId = xsbId;
this.xszdsl = new Integer(1);
} public void increment() {
this.xszdsl += 1;
} }
public class Xsjgb extends EntityBean {

    @Transient
private static final long serialVersionUID = 1L;
/**
* 表Id
*/private String bId; /**
* 数据包标识 (可作为表名的组成部分)
*/private String xsjgbId; public Xsjgb(@NotEmpty String bId, @NotEmpty String xsjgbId) {
this.bId = bId;
this.xsjgbId = xsjgbId;
}
}
public class Xsjgbxx implements Serializable {

    private static final long serialVersionUID = -6162813536053634882L;

    /**
* 表Id
*/
private String bId; /**
* 表字段数量
*/
private Integer zdsl; /**
* 可能存在相似结构的表
*/
private List<XsjgGxbxx> xsjgGxbxxes; public Xsjgbxx(String bId, Integer zdsl) {
this.bId = bId;
this.zdsl = zdsl;
this.xsjgGxbxxes = new ArrayList<>();
}
}
public class XsjgbzdxxDTO implements Serializable {

    private static final long serialVersionUID = 8209530764411503009L;

    /**
* 字段英文名
*/
private String zdywm; /**
* 字段中文名
*/
private String zdzwm; /**
* 字段类型
*/
private String zdlx; /**
* 相同字段的表Id,英文逗号分隔
*/
private String bIds; /**
* 相同字段的表字段数量,英文逗号分隔
*/
private String zdsl; }

Java实现相似结构表算法的更多相关文章

  1. java学习-循环结构-查找算法-顺序查找

    今天回顾了简单算法,顺序查找.发现了数组出现重复数字,无法输出第二个位置就跳出循环了. 利用所学知识解决了.放上代码,同时在代码里给大家分享思路. 欢迎大神教导,欢迎指正. ; System.out. ...

  2. 数据结构与算法【Java】08---树结构的实际应用

    前言 数据 data 结构(structure)是一门 研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构才可以编写出更加漂亮,更加有效率的代码. 要学习好数据结构就要多多考虑如何将生 ...

  3. java结构与算法之选择排序

    一 .java结构与算法之选择排序(冒择路兮快归堆) 什么事选择排序:从一组无序数据中选择出中小的的值,将该值与无序区的最左边的的值进行交换. 简单的解释:假设有这样一组数据 12,4,23,5,找到 ...

  4. Java工具类_表结构自动生成对应的实体类、Mapper.xml文件、Dao类

    import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWrit ...

  5. 深入理解java虚拟机【垃圾回收算法】

    Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...

  6. 第一阶段:Java内功秘籍-线性表

    前言 为什么要学习数据结构与算法,如果你学会了做安卓,javaweb,前端等,都是你的武功秘籍,但是如果你的内功不够好,再厉害的功夫也是白费. 数据结构和算法:什么是数据结构,什么是数据,在计算机内部 ...

  7. 翻译Java虚拟机的结构

    英文原版:  https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 直接谷歌翻译: Java SE规范 > Java虚拟机 ...

  8. Hash表算法

    出处:http://blog.csdn.net/v_JULY_v 第一部分:Top K 算法详解问题描述百度面试题:    搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的 ...

  9. [java基础]循环结构2

    [java基础]循环结构2 写了几个循环结构练习~记录一下~~ 1:99乘法表 /** 文件路径:G:\JavaByHands\循环语句\ 文件名称:GameForFor.java 编写时间:2016 ...

  10. paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)

    paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1     锁的缺点 2     CAS(Compare ...

随机推荐

  1. quarkus数据库篇之三:单应用同时操作多个数据库

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 一个应用同时连接多个数据库进行操作,这是常见 ...

  2. Spring HandlerInterceptor工作机制

    本文以一个通过正常注册拦截器流程注册拦截器失败的实际场景,来带领大家阅读源码,体会Spring的HandlerInterceptor拦截器整个工作流程 简单认识 org.springframework ...

  3. 论文解读(IW-Fit)《Better Fine-Tuning via Instance Weighting for Text Classification》

    Note:[ wechat:Y466551 | 可加勿骚扰,付费咨询 ] 论文信息 论文标题:Better Fine-Tuning via Instance Weighting for Text Cl ...

  4. 从原理聊 JVM(五):JVM 的编译过程和优化手段

    一.前端编译 前端编译就是将Java源码文件编译成Class文件的过程,编译过程分为4步: 1 准备 初始化插入式注解处理器(Annotation Processing Tool). 2 解析与填充符 ...

  5. 在本地运行Kusto服务器

    我喜欢Kusto (或商用版本 Azure Data Explorer,简称 ADX) 是大家可以有目共睹的,之前还专门写过这方面的书籍,请参考 大数据分析新玩法之Kusto宝典, 很可能在今年还会推 ...

  6. Leetcode刷题笔记——二分法

    二分法是搜索算法中极其典型的方法,其要求输入序列有序并可随机访问.算法思想为 输入:有序数组nums,目的数值target 要求输出:如果target存在在数组中,则输出其index,否则输出-1 将 ...

  7. 弹性数据库连接池探活策略调研(一)——HikariCP

    调研背景: 数据库连接建立是比较昂贵的操作(至少对于 OLTP),不仅要建立 TCP 连接外还需要进行连接鉴权操作,所以客户端通常会把数据库连接保存到连接池中进行复用.连接池维护到弹性数据库(JED) ...

  8. FFmpeg中的常用结构体分析

    一.前言 在学习使用FFmpeg进行编解码时,我们有必要先去熟悉FFmpeg中的常用结构体,只有对它们的含义和用途有深刻的了解,我们才能为后面的学习打下坚实的基础.所以,这篇文章将会介绍这些常用的结构 ...

  9. Web攻防--Java_SQL注入--XXE注入-- SSTI模板注入--SPEL表达式注入

    预编译 编译器在编译sql语句时,会依次进行词法分析.语法分析.语义分析等操作, 预编译技术会让数据库跳过编译阶段,也就无法就进行词法分析,关键字不会被拆开,注入语句也就不会被识别为SQL的关键字,从 ...

  10. CCF PTA&中国科教工作者协会联合认证

    首页 项目简介 条例规定 通知公告 组织机构 服务中心 联系我们 登录|注册 当前位置:首页 > 新闻动态 开放报名:CCF PTA&中国科教工作者协会联合认证 发布时间: 2023-0 ...