日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql建表语句转达梦_MySQL建表语句转PostgreSQL建表语句全纪录

發(fā)布時間:2023/12/10 数据库 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql建表语句转达梦_MySQL建表语句转PostgreSQL建表语句全纪录 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

個人習慣用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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。