Mysql建表脚本转ClinkHouse建表脚本
Posted 我永远信仰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql建表脚本转ClinkHouse建表脚本相关的知识,希望对你有一定的参考价值。
mysql建表脚本转CK
前置知识
主要是类型的转换、和空、非空的问题
整形
-
ClickHouse则直接使用Int8、Int16、Int32和Int64指代4种大小的Int类型,其末尾的数字正好表明了占用字节的大小(8位=1字节)
-
mysql中
: int(M)的作用于int的范围明显是无关的,int(M)只是用来显示数据的宽度,我们能看到的宽度。当字段被设计为int类型,那么它的范围就已经被写死了(-2147483648~2147483647),与M无关。
CK的NOT NULL、NULL和Nullable的区别
- 如果字段声明为
not null
它的默认值已由它的类型而定,不允许再为其设置默认值,比如int为0,String为空串。不需要显式声明 - 如果字段显式声明为
null
,默认值为NULL。 - 如果字段声明为
Nullable
,默认为NULL,可设置默认值,损耗性能。
/**
* @Author yhchen
* @Date 2022/3/8 10:22
*/
public class MysqlToCK2
public static void main(String[] args)
//将sql复制到这里
String createTable = "DROP TABLE IF EXISTS `runoob_tbl`;\\n" +
"CREATE TABLE IF NOT EXISTS `runoob_tbl`(\\n" +
" `runoob_id` int UNSIGNED AUTO_INCREMENT,\\n" +
" `runoob_title` VARCHAR(100) NOT NULL,\\n" +
" `runoob_author` VARCHAR(40) NOT NULL,\\n" +
" `submission_date` DATE,\\n" +
" PRIMARY KEY ( `runoob_id` )\\n" +
")ENGINE=InnoDB DEFAULT CHARSET=utf8;";
String res = changeMysqlTableToClickHouse(createTable);
System.out.println("转换后的建表语句为:");
System.out.println(res);
System.out.println("需要删除ENGINE的上一行最后的一个逗号");
public static String changeMysqlTableToClickHouse(String tableName)
String tables = tableName;
String primaryKey = "`id`";//默认id
String[] rows = tables.split("\\n");
StringBuilder replaceTables = new StringBuilder();
Boolean haveKey = false;
int i = 0;
for (String row : rows)
// 注释,不处理
if (row.contains("--"))
replaceTables.append(row + "\\n");
continue;
if (row.contains("KEY"))
if (row.contains("PRIMARY"))
haveKey = true;
primaryKey = row.substring(row.indexOf("(") + 1, row.indexOf(")"));
// 跳过、不添加
continue;
if (row.contains("ENGINE=InnoDB"))
// 引擎替换
row = ") ENGINE = ReplacingMergeTree";
// 无关删除
String changeRow = row.replaceAll("AUTO_INCREMENT", "")
.replaceAll("CHARACTER SET utf8mb4", "")
.replaceAll("CHARACTER SET utf8", "")
.replaceAll("ON UPDATE CURRENT_TIMESTAMP", "")
.replaceAll("CURRENT_TIMESTAMP", "")
.replaceAll("( DEFAULT CHARSET).*", "")
// 时间替换
.replaceAll("datetime DEFAULT NULL", " DateTime ")
.replaceAll(" datetime ", " DateTime ");
/*String规则*/
// 为空,字符串
changeRow = changeRow.replaceAll("(` ).*(char).*(DEFAULT NULL)", "` String NULL");
changeRow = changeRow.replaceAll("(` ).*(char).*(DEFAULT '')", "` String");
// changeRow = changeRow.replaceAll("(DEFAULT '')", "NULL");
// 非空,字符串
changeRow = changeRow.replaceAll("(` ).*(char).*(NOT NULL)", "` String");
changeRow = changeRow.replaceAll("text", "String");
changeRow = changeRow.replaceAll("(DEFAULT NULL)", "NULL");
changeRow = changeRow.replaceAll("(NOT NULL)", "");
// 以空格分割
String[] changeColumns = changeRow.split("[ ]");
// System.out.println(changeRow);
// 含有int的替换规则
if (changeColumns[3].contains("int") || changeColumns[3].contains("bigint")
||changeColumns[3].contains("INT"))
changeColumns[3].replaceAll("INT","int");
changeColumns[3].replaceAll("BIGINT","bigint");
// 将括号内的数字拿出来
int length = Integer.parseInt(changeColumns[3]
.replaceAll("bigint", "")
.replaceAll("tinyint", "")
.replaceAll("int", "")
.replaceAll("\\\\(", "")
.replaceAll("\\\\)", ""));
// 获取数据类型
String type = changeColumns[3].substring(0, changeColumns[3].indexOf("("));
// 处理int 是否可以为空值
String last = " NULL";
String[] _int = "Int8", "Int16", "Int32", "Int64";
if (changeRow.contains("DEFAULT NULL"))
changeRow = changeRow.replaceAll("DEFAULT NULL", "");
for (int j = 0; j < _int.length; j++)
_int[j] = _int[j] + last;
if ("tinyint".equals(type))
changeRow = changeRow
.replaceFirst(type + "\\\\(" + length + "\\\\)", _int[0]);
else if ("smallint".equals(type))
changeRow = changeRow
.replaceFirst(type + "\\\\(" + length + "\\\\)", _int[1]);
else if ("int".equals(type) || "mediumint".equals(type))
changeRow = changeRow
.replaceFirst(type + "\\\\(" + length + "\\\\)", _int[2]);
else
changeRow = changeRow
.replaceFirst(type + "\\\\(" + length + "\\\\)", _int[3]);
replaceTables.append(changeRow.trim() + "\\n");
if (i == 0)
replaceTables.append("\\n");
i++;
if (replaceTables.toString().contains(",) ENGINE = Memory"))
String temp = replaceTables.substring(0, replaceTables.indexOf(",) ENGINE = Memory"));
replaceTables = new StringBuilder(temp + ") ENGINE = Memory ");
replaceTables.toString().replaceAll("CREATE TABLE `" + tableName + "`", tableName + "_local");
if (haveKey)
replaceTables.append("PRIMARY KEY " + primaryKey);
replaceTables.append("\\nORDER BY " + primaryKey);
replaceTables.append(";");
return replaceTables.toString();
以上是关于Mysql建表脚本转ClinkHouse建表脚本的主要内容,如果未能解决你的问题,请参考以下文章