例如:公司某一个系统的库有三百张表,在不熟悉项目的情况下,打开数据库看到一列列的表,很不清晰,对新入职同事很不友好。
需求分析:我们一个系统里,可能有很多个模块,例如商城系统中有商品模块、券模块、店铺模块等,没个模块都有几十张表,每个模块需要生成如下关系图:(吐槽一下,navicat逆向的图没powerdesigner好看)
技术方案:使用工具:navicat
navicat是国内的一款数据库客户端,内置有模型功能,可以实现需求中,选中一个模块的所有表,逆向表到模型,从而生成er图,但如果选中表中,没有外键关联,生成出来的模型,并没有像需求中那样,有直观的线连接,所以需要给对应表生成外键sql。
从navicat中选中所有表导出为sql时发现下图规律
解决方案: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);
外键语句不要去开发测试生产等环境执行,要自己在本地新建库
新建库时,只转结构就好,不然数据多了,外键语句执行特慢
结束后,想要那些表之间的关系图,只需要选中后逆向表到模型即可得到需求中的效果
如果资金充裕,可以打赏请我喝杯咖啡,谢谢 thanks♪(・ω・)ノ
以上就是如何快速生成mysql数据库关系图的详细内容。
