一文教你快速生成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内存空间效率问题的深入探究
May 17 Redis
5分钟教你docker安装启动redis全教程(全新方式)
May 29 Redis
深入理解redis中multi与pipeline
Jun 02 Redis
Windows中Redis安装配置流程并实现远程访问功能
Jun 07 Redis
redis不能访问本机真实ip地址的解决方案
Jul 07 Redis
在项目中使用redis做缓存的一些思路
Sep 14 Redis
基于Redis结合SpringBoot的秒杀案例详解
Oct 05 Redis
Redis三种集群模式详解
Oct 05 Redis
Redis中缓存穿透/击穿/雪崩问题和解决方法
Dec 04 Redis
分布式Redis Cluster集群搭建与Redis基本用法
Feb 24 Redis
使用Redis实现点赞取消点赞的详细代码
Mar 20 Redis
redis复制有可能碰到的问题汇总
Apr 03 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
3种平台下安装php4经验点滴
2006/10/09 PHP
php 遍历显示文件夹下所有目录、所有文件的函数,没有分页的代码
2008/11/14 PHP
一个严格的PHP Session会话超时时间设置方法
2014/06/10 PHP
php获取Google机器人访问足迹的方法
2015/04/15 PHP
使用PHP进行微信公众平台开发的示例
2015/08/21 PHP
thinkPHP自动验证机制详解
2016/12/05 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
PHP实现微信公众号验证Token的示例代码
2019/12/16 PHP
yii框架结合charjs实现统计30天数据的方法
2020/04/04 PHP
JS中==与===操作符的比较
2009/03/21 Javascript
克隆javascript对象的三个方法小结
2011/01/12 Javascript
在Javascript中 声明时用&quot;var&quot;与不用&quot;var&quot;的区别
2013/04/15 Javascript
关于innerHTML后丢失动态绑定的EVENT问题解决方法
2013/05/19 Javascript
JavaScript自定义事件介绍
2013/08/29 Javascript
JS中的构造函数详细解析
2014/03/10 Javascript
jQuery Validate表单验证插件 添加class属性形式的校验
2016/01/18 Javascript
JS检测页面中哪个HTML标签触发点击事件的方法
2016/06/17 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
2017/03/14 Javascript
requireJS模块化实现返回顶部功能的方法详解
2017/10/16 Javascript
python发送HTTP请求的方法小结
2015/07/08 Python
python中类和实例如何绑定属性与方法示例详解
2017/08/18 Python
Python数据结构与算法之图结构(Graph)实例分析
2017/09/05 Python
python实现requests发送/上传多个文件的示例
2018/06/04 Python
python自定义线程池控制线程数量的示例
2019/02/22 Python
OpenCV+face++实现实时人脸识别解锁功能
2019/08/28 Python
python字符串反转的四种方法详解
2019/12/02 Python
Python列表倒序输出及其效率详解
2020/03/04 Python
python 通过 pybind11 使用Eigen加速代码的步骤
2020/12/07 Python
python实现录制全屏和选择区域录屏功能
2021/02/05 Python
如何估计一张表的大小(假设该表中有1万条数据)
2016/03/27 面试题
软件工程师面试题
2012/06/25 面试题
购房协议书范本
2014/04/11 职场文书
2014年人事科工作总结
2014/11/19 职场文书
2014年服务员个人工作总结
2014/12/23 职场文书
通讯稿范文
2015/07/22 职场文书
springboot利用redis、Redisson处理并发问题的操作
2021/06/18 Java/Android