Mysql建表脚本转ClickHouse建表脚本

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的区别

  1. 如果字段声明为 not null它的默认值已由它的类型而定,不允许再为其设置默认值,比如int为0,String为空串。不需要显式声明
  2. 如果字段显式声明为null,默认值为NULL。
  3. 如果字段声明为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;";
        System.out.println("请检查语句,不要有空行 也就是只有'\\n'");
        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();
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值