一文教你快速生成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 15 Redis
详解redis分布式锁的这些坑
May 19 Redis
详解缓存穿透击穿雪崩解决方案
May 28 Redis
Redis基于Bitmap实现用户签到功能
Jun 20 Redis
Redis做数据持久化的解决方案及底层原理
Jul 15 Redis
详解redis在微服务领域的贡献
Oct 16 Redis
解决linux下redis数据库overcommit_memory问题
Feb 24 Redis
使用Redis实现点赞取消点赞的详细代码
Mar 20 Redis
Redis 哨兵机制及配置实现
Mar 25 Redis
Redis中key的过期删除策略和内存淘汰机制
Apr 12 Redis
详解Redis的三种常用的缓存读写策略步骤
May 06 Redis
利用Redis实现点赞功能的示例代码
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 上传文件的方法(类)
2009/07/30 PHP
微盾PHP脚本加密专家php解密算法
2020/09/13 PHP
使用Linux五年积累的一些经验技巧
2013/06/20 PHP
php输出全球各个时区列表的方法
2015/03/31 PHP
Laravel 的数据库迁移的方法
2017/07/31 PHP
window.addeventjs事件驱动函数集合addEvent等
2008/02/19 Javascript
避免 showModalDialog 弹出新窗体的原因分析
2010/05/31 Javascript
转义字符(\)对JavaScript中JSON.parse的影响概述
2013/07/17 Javascript
jQuery 无限级菜单的简单实例
2014/02/21 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
2015/03/01 Javascript
CSS中position属性之fixed实现div居中
2015/12/14 Javascript
Web安全测试之XSS实例讲解
2016/08/15 Javascript
详解angularJs中自定义directive的数据交互
2017/01/13 Javascript
微信小程序 刷新上拉下拉不会断详细介绍
2017/05/11 Javascript
DataTables添加额外的查询参数和删除columns等无用参数实例
2017/07/04 Javascript
使用JavaScript通过前端发送电子邮件
2020/05/22 Javascript
JS使用Chrome浏览器实现调试线上代码
2020/07/23 Javascript
[01:34]2014DOTA2展望TI 剑指西雅图VG战队专访
2014/06/30 DOTA
Python下singleton模式的实现方法
2014/07/16 Python
python实现查询苹果手机维修进度
2015/03/16 Python
使用Python爬取最好大学网大学排名
2018/02/24 Python
利用Python进行数据可视化常见的9种方法!超实用!
2018/07/11 Python
python实现诗歌游戏(类继承)
2019/02/26 Python
Eclipse配置python默认头过程图解
2020/04/26 Python
Python Request类源码实现方法及原理解析
2020/08/17 Python
Nisbets法国:英国最大的厨房和餐饮设备供应商
2019/03/18 全球购物
介绍Java的内部类
2012/10/27 面试题
零件设计自荐信范文
2013/11/27 职场文书
公司薪酬管理制度
2014/01/31 职场文书
工厂标语大全
2014/10/06 职场文书
2015年“公民道德宣传日”活动方案
2015/05/06 职场文书
物业公司管理制度
2015/08/05 职场文书
清洁工工作总结
2015/08/11 职场文书
药品销售员2015年终工作总结
2015/10/22 职场文书
Golang标准库syscall详解(什么是系统调用)
2021/05/25 Golang
Consul在linux环境的集群部署
2022/04/08 Servers