mysql建表语句转达梦_MySQL建表语句转PostgreSQL建表语句全纪录
個人習慣用MySQL workbench EER數(shù)據(jù)建模,然后生成SQL語句到數(shù)據(jù)庫中執(zhí)行,這樣表之間的關(guān)系比較直觀。
像下面這樣:
畫圖
正向工程,生成DDL語句:
忽略生成外鍵,以及外鍵索引啥的:
生成的DDL語句:
到數(shù)據(jù)庫執(zhí)行。
踩坑了
最近團隊微調(diào),我被調(diào)整到另一個小團隊。前兩天接了個新需求,于是我依然使用MySQL workbench EER建模,結(jié)果好不容易建模完成了,卻被告知這個項目用的數(shù)據(jù)庫是PostgreSQL!
于是就面臨如下幾種選擇:
重新找個支持導出PostgreSQL DDL語句的建模軟件,再弄一遍。據(jù)我所知,macOS平臺里沒啥好的數(shù)據(jù)建模軟件…
PowerDesigner用不了(除非裝虛擬機,或者Wine);
Navicat太難用了(居然有人說Navicat是最好的數(shù)據(jù)庫客戶端,我只能給一個大寫的服,在我看來,這貨連IDEA自帶數(shù)據(jù)庫管理都比不上……這觀點可能有點偏激,但現(xiàn)狀是我做個查詢,Navicat把查詢按鈕藏得很深);
IDEA宣布會開發(fā)類似功能,但一直沒有動靜;
開源的PDMan,體驗挺不錯,但也得連個數(shù)據(jù)庫控制版本。
依然用MySQL workbench導出DDL,然后自己將MySQL DDL轉(zhuǎn)換成PostgreSQL DDL。
我選擇了自己轉(zhuǎn)換SQL語句。
開源的DDL轉(zhuǎn)換工具
既然要轉(zhuǎn)換SQL語句,我心想,業(yè)界肯定有相關(guān)的工具啊。于是上萬能的GayHub搜了下,還真有,列出來:
mysql-to-postgres:https://github.com/maxlapshin/mysql2postgres
mysql-postgresql-converter:https://github.com/lanyrd/mysql-postgresql-converter
多款工具配合使用:https://yq.aliyun.com/articles/241 (不得不佩服這兄弟真有耐心啊!)
然而試用后,內(nèi)心是崩潰的……生成出來的DDL要么有誤,要么沒有注釋。
自己開發(fā)工具
考慮到我的訴求其實非常簡單,只是個DDL語句轉(zhuǎn)換而已,自己開發(fā)一個也不難。而且之前研讀Mybatis通用Mapper源碼時,知道Java世界里有個jsqlparser 的工具。
花了10分鐘簡單了解了下jsqlparser 后,就開擼開發(fā)工具了……花了20分鐘,初版寫完了,然后和該項目的同事又花了20分鐘驗證了下,最終確定了如下的版本。代碼貼出來:
加依賴:
com.github.jsqlparserjsqlparser1.2
寫代碼:
public class MysqlDdl2PgDdlUtil { public static void main(String[] args) throws IOException, JSQLParserException { // 你的MySQL DDL路徑 String mysqlDDLPath = "/Users/reno/Downloads/mysql.sql"; String dDLs = FileUtils.readFileToString(new File(mysqlDDLPath)); System.out.println(dDLs); System.out.println("++++++++++開始轉(zhuǎn)換SQL語句+++++++++++++"); Statements statements = CCJSqlParserUtil.parseStatements(dDLs); statements.getStatements() .stream() .map(statement -> (CreateTable) statement).forEach(ct -> { Table table = ct.getTable(); List columnDefinitions = ct.getColumnDefinitions(); List comments = new ArrayList<>(); List collect = columnDefinitions.stream() .peek(columnDefinition -> { List columnSpecStrings = columnDefinition.getColumnSpecStrings(); int commentIndex = getCommentIndex(columnSpecStrings); if (commentIndex != -1) { int commentStringIndex = commentIndex + 1; String commentString = columnSpecStrings.get(commentStringIndex); String commentSql = genCommentSql(table.toString(), columnDefinition.getColumnName(), commentString); comments.add(commentSql); columnSpecStrings.remove(commentStringIndex); columnSpecStrings.remove(commentIndex); } columnDefinition.setColumnSpecStrings(columnSpecStrings); }).collect(Collectors.toList()); ct.setColumnDefinitions(collect); String createSQL = ct.toString() .replaceAll("`", """) .replaceAll("BIGINT UNIQUE NOT NULL AUTO_INCREMENT", "BIGSERIAL PRIMARY KEY") .replaceAll("BIGINT NULL AUTO_INCREMENT", "BIGSERIAL PRIMARY KEY") .replaceAll("BIGINT NOT NULL AUTO_INCREMENT", "BIGSERIAL PRIMARY KEY") .replaceAll("INT NOT NULL AUTO_INCREMENT", "BIGSERIAL PRIMARY KEY") .replaceAll("INT NULL AUTO_INCREMENT", "BIGSERIAL PRIMARY KEY") .replaceAll("IF NOT EXISTS", "") .replaceAll("TINYINT", "SMALLINT") .replaceAll("DATETIME", "TIMESTAMP") .replaceAll(", PRIMARY KEY \("id"\)", ""); // 如果存在表注釋 if (createSQL.contains("COMMENT")) { createSQL = createSQL.substring(0, createSQL.indexOf("COMMENT")); } System.out.println(createSQL + ";"); comments.forEach(t -> System.out.println(t.replaceAll("`", """) + ";")); }); } /** * 獲得注釋的下標 * * @param columnSpecStrings columnSpecStrings * @return 下標 */ private static int getCommentIndex(List columnSpecStrings) { for (int i = 0; i < columnSpecStrings.size(); i++) { if ("COMMENT".equalsIgnoreCase(columnSpecStrings.get(i))) { return i; } } return -1; } /** * 生成COMMENT語句 * * @param table 表名 * @param column 字段名 * @param commentValue 描述文字 * @return COMMENT語句 */ private static String genCommentSql(String table, String column, String commentValue) { return String.format("COMMENT ON COLUMN %s.%s IS %s", table, column, commentValue); }}
如代碼所示,目前是借助jsqlparser 的SQL解析能力配合字符串替換的方式生成PostgreSQL的。
效果演示
轉(zhuǎn)換前的DDL:
-- ------------------------------------------------------- Table `user`-- -----------------------------------------------------CREATE TABLE IF NOT EXISTS `user` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT "id", `username` VARCHAR(16) NOT NULL COMMENT "用戶名", `email` VARCHAR(255) NULL COMMENT "郵件", `password` VARCHAR(32) NOT NULL COMMENT "密碼", `create_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP COMMENT "創(chuàng)建時間", PRIMARY KEY (`id`));-- ------------------------------------------------------- Table `movie`-- -----------------------------------------------------CREATE TABLE IF NOT EXISTS `movie` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT "Id", `name` VARCHAR(255) NOT NULL COMMENT "名稱", `user_id` INT NOT NULL COMMENT "user.id", PRIMARY KEY (`id`))COMMENT = "電影表";
轉(zhuǎn)換后的DDL:
CREATE TABLE "user"( "id" BIGSERIAL PRIMARY KEY, "username" VARCHAR(16) NOT NULL, "email" VARCHAR(255) NULL, "password" VARCHAR(32) NOT NULL, "create_time" TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP);COMMENT ON COLUMN "user"."id" IS "id";COMMENT ON COLUMN "user"."username" IS "用戶名";COMMENT ON COLUMN "user"."email" IS "郵件";COMMENT ON COLUMN "user"."password" IS "密碼";COMMENT ON COLUMN "user"."create_time" IS "創(chuàng)建時間";CREATE TABLE "movie"( "id" BIGSERIAL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "user_id" INT NOT NULL);COMMENT ON COLUMN "movie"."id" IS "Id";COMMENT ON COLUMN "movie"."name" IS "名稱";COMMENT ON COLUMN "movie"."user_id" IS "user.id";
效果還是不錯的,基本達到了我的要求。
不足
目前工具代碼比較屎,如果想要改進,應(yīng)該是要讓工具理解MySQL DDL的詞法,然后構(gòu)建成例如Table、Column、Comment、Constraint、Index等對象例如:
class Table { private String name; private Column column;}class Column { private String name; private String type; // 約束,例如非空等 private Set constraints; // 索引 private Index index;}class Index { private String name; private String type;}enum Constraint { NOT_NULL,...;}
然后抽象一個方言枚舉,并為不同的方言制作一個DDL Generator Handler,然后根據(jù)不同的方言生成不同數(shù)據(jù)庫平臺的DDL語句。
為什么不改進?因為沒有時間,工具是為工作服務(wù)的,目前能達到我的目的,就沒動力修改了,未來有需求再改進吧。
作者:周立_ITMuch
原文:https://my.oschina.net/eacdy/blog/2995462
本文僅代表作者個人觀點,不代表巔云官方發(fā)聲,對觀點有疑義請先聯(lián)系作者本人進行修改,若內(nèi)容非法請聯(lián)系平臺管理員,郵箱2522407257@qq.com。更多相關(guān)資訊,請到巔云www.yinxi.net學習互聯(lián)網(wǎng)營銷技術(shù)請到巔云建站www.yx10011.com。
總結(jié)
以上是生活随笔為你收集整理的mysql建表语句转达梦_MySQL建表语句转PostgreSQL建表语句全纪录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程程序排错总结
- 下一篇: linux cmake编译源码,linu