一文教你快速生成MySQL数据库关系图


Posted in Redis onJune 28, 2022

需求描述:

在公司老旧系统里,数据库表很多,但是在设计之初并没有建立好关系图,导致新人刚入职,面对N个库,每个库几百张表,很不方便。

例如:公司某一个系统的库有三百张表,在不熟悉项目的情况下,打开数据库看到一列列的表,很不清晰,对新入职同事很不友好。

一文教你快速生成MySQL数据库关系图

需求分析:

我们一个系统里,可能有很多个模块,例如商城系统中有商品模块、券模块、店铺模块等,没个模块都有几十张表,每个模块需要生成如下关系图:(吐槽一下,Navicat逆向的图没PowerDesigner好看)

一文教你快速生成MySQL数据库关系图

技术方案:

使用工具:Navicat

        Navicat是国内的一款数据库客户端,内置有模型功能,可以实现需求中,选中一个模块的所有表,逆向表到模型,从而生成ER图,但如果选中表中,没有外键关联,生成出来的模型,并没有像需求中那样,有直观的线连接,所以需要给对应表生成外键SQL。

        从Navicat中选中所有表导出为SQL时发现下图规律

一文教你快速生成MySQL数据库关系图

解决方案:

1. 把每个表语句拆分出来

2. 主表与关联表,主表不需要生产外键,关联表可以通过小撇号判断是否需要外键

3. 说再多文字不如读一遍代码更清晰

package com.example.demo;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
 
public class MysqlERGenerate {
    public static void main(String[] args) throws IOException {
        StringBuilder builder = new StringBuilder();
        // 输入从Navicat导出的表结构sql文件 将文件读取出来 放入字符串中
        InputStream is = Files.newInputStream(Paths.get("C:\\Users\\admin\\Desktop\\ddl.sql"));
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        line = reader.readLine();
        while (line != null) {
            builder.append(line);
            builder.append("\n");
            line = reader.readLine();
        }
        reader.close();
        is.close();
        String sql = builder.toString();
 
        // 按照规律 使用CREATE TABLE进行分割 并删掉一个文件注释部分
        String[] split = sql.split("CREATE TABLE");
        List<String> list = new ArrayList<>(Arrays.asList(split));
        list.remove(0);
        // 使用开头两个小撇号进行截取 得到表名 转为Map<表名, SQL>
        Map<String, String> collect = list.stream().collect(Collectors.toMap(k -> {
            int firstIndex = k.indexOf("`");
            return k.substring(++firstIndex, k.indexOf("`", firstIndex));
        }, v -> v));
 
        // 需要创建外键的字段与对应的主表名称 Map<外键名, 外键主表名>
        Map<String, String> foreignKey = new HashMap<>();
        foreignKey.put("ticket_no", "ticket");
        foreignKey.put("ticket_define_no", "ticket_define");
        foreignKey.put("pro_no", "pro_main");
        // 循环判断,生成外键SQL
        Set<String> foreignKeyFields = foreignKey.keySet();
        for (String mainTableName : collect.keySet()) {
            String val = collect.get(mainTableName);
            for (String field : foreignKeyFields) {
                if (!mainTableName.equals(foreignKey.get(field)) && val.indexOf("`" + field + "`") > 0) {
                    String createForeignKeySql = String.format("alter table %s add foreign key %s(%s) references %s(%s);", mainTableName, mainTableName + field + System.currentTimeMillis(), field, foreignKey.get(field), field);
                    System.out.println(createForeignKeySql);
                }
            }
        }
    }
}

运行效果:只复制出部分,实际远比这个多

alter table pro_param add foreign key pro_parampro_no1650765563395(pro_no) references pro_main(pro_no);
alter table pro_shop_priority_his_20200805 add foreign key pro_shop_priority_his_20200805pro_no1650765563423(pro_no) references pro_main(pro_no);
 
alter table ticket_define_shop add foreign key ticket_define_shopticket_define_no1650765563423(ticket_define_no) references ticket_define(ticket_define_no);
alter table ticket_define_item add foreign key ticket_define_itemticket_define_no1650765563425(ticket_define_no) references ticket_define(ticket_define_no);
 
alter table ticket_his_2019 add foreign key ticket_his_2019ticket_no1650765563432(ticket_no) references ticket(ticket_no);
alter table ticket_his_2018 add foreign key ticket_his_2018ticket_no1650765563433(ticket_no) references ticket(ticket_no);

一文教你快速生成MySQL数据库关系图

  • 外键语句不要去开发测试生产等环境执行,要自己在本地新建库
  • 新建库时,只转结构就好,不然数据多了,外键语句执行特慢
  • 结束后,想要那些表之间的关系图,只需要选中后逆向表到模型即可得到需求中的效果
  • 如果资金充裕,可以打赏请我喝杯咖啡,谢谢 Thanks♪(・ω・)ノ

总结

到此这篇关于快速生成MySQL数据库关系图的文章就介绍到这了,更多相关生成MySQL关系图内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
Redis持久化与主从复制的实践
Apr 27 Redis
详解Redis实现限流的三种方式
Apr 27 Redis
Redis延迟队列和分布式延迟队列的简答实现
May 13 Redis
详解Redis复制原理
Jun 04 Redis
Redis可视化客户端小结
Jun 10 Redis
比较几种Redis集群方案
Jun 21 Redis
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
Feb 12 Redis
Redis高可用集群redis-cluster详解
Mar 20 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
Apr 07 Redis
windows安装 redis 6.2.6最新步骤详解
Apr 26 Redis
Redis入门基础常用操作命令整理
Jun 01 Redis
Redis+AOP+自定义注解实现限流
Jun 28 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 #Redis
浅谈Redis变慢的原因及排查方法
使用Redis实现分布式锁的方法
Jun 16 #Redis
关于Redis的主从复制及哨兵问题
Jun 16 #Redis
Redis实现分布式锁的五种方法详解
Redis实现短信验证码登录的示例代码
Jun 14 #Redis
Redis批量生成数据的实现
Jun 05 #Redis
You might like
PHP中显示格式化的用户输入
2006/10/09 PHP
PHPWind 发帖回帖Api PHP版打包下载
2010/02/08 PHP
discuz程序的PHP加密函数原理分析
2011/08/05 PHP
PHP exif扩展方法开启详解
2014/07/28 PHP
Yii 2中的load()和save()示例详解
2017/08/03 PHP
PHP模型Model类封装数据库操作示例
2019/03/14 PHP
PHP添加文字水印或图片水印的水印类完整源代码与使用示例
2019/03/18 PHP
使用jQuery模板来展现json数据的代码
2010/10/22 Javascript
JQuery的Ajax请求实现局部刷新的简单实例
2014/02/11 Javascript
如何在MVC应用程序中使用Jquery
2014/11/17 Javascript
Jquery插件实现点击获取验证码后60秒内禁止重新获取
2015/03/13 Javascript
JavaScript中获取HTML元素值的三种方法
2016/06/20 Javascript
Bootstrap基本模板的使用和理解1
2016/12/14 Javascript
微信小程序 仿美团分类菜单 swiper分类菜单
2017/04/12 Javascript
详解nodejs微信jssdk后端接口
2017/05/25 NodeJs
浅谈angular表单提交中ng-submit的默认使用方法
2018/09/30 Javascript
JavaScript继承的特性与实践应用深入详解
2018/12/30 Javascript
移动端自适应flexible.js的使用方法(不用三大框架,仅写一个单html页面使用)推荐
2019/04/02 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
Python设计模式之抽象工厂模式
2016/08/25 Python
Python中的id()函数指的什么
2017/10/17 Python
使用Python 正则匹配两个特定字符之间的字符方法
2018/12/24 Python
使用Python脚本从文件读取数据代码实例
2020/01/19 Python
通过Python实现Payload分离免杀过程详解
2020/07/13 Python
python与js主要区别点总结
2020/09/13 Python
Python三维绘图之Matplotlib库的使用方法
2020/09/20 Python
pytorch 实现L2和L1正则化regularization的操作
2021/03/03 Python
Currentbody法国:健康与美容高科技产品
2020/08/16 全球购物
化学系大学生自荐信范文
2014/03/01 职场文书
大学生标准自荐书
2014/06/15 职场文书
2014年秋季开学寄语
2014/08/02 职场文书
我与祖国共奋进演讲稿
2014/09/13 职场文书
小学教研工作总结2015
2015/05/13 职场文书
一个都不能少观后感
2015/06/04 职场文书
红色经典电影观后感
2015/06/18 职场文书
OpenCV-Python实现人脸美白算法的实例
2021/06/11 Python