生成Hive数据字典

生产中Hive的元数据存储在MySQL中,构建数据字典我们可以通过查询元数据表,导出查询结果后生成自己想要的文档。
下面我会一步一步介绍如何生成markdown格式的数据字典文档。

定义SQL

首先废话不多说,贴出我们需要的在MySQL中使用的SQL。

SELECT
	a. NAME as SCHEMA_NAME,-- 数据库名称
	t.TBL_NAME as TABLE_NAME,-- 表名
	b.PARAM_VALUE as TABLE_COMMENT,-- 表注释
	e.INTEGER_IDX as COLUMN_ID,-- 字段序号
	e.COLUMN_NAME ,-- 字段名
    e.TYPE_NAME as COLUMN_DATA_TYPE,-- 字段类型
    f.PART_KEYS as PART_COLUMN,-- 分区字段
	e.COMMENT-- 字段注释
FROM
	TBLS t
	JOIN DBS a ON t.DB_ID = a.DB_ID
	LEFT JOIN (select TBL_ID,PARAM_VALUE FROM TABLE_PARAMS where PARAM_KEY='comment') b ON t.TBL_ID = b.TBL_ID
	LEFT JOIN SDS c ON t.SD_ID = c.SD_ID
	LEFT JOIN CDS d ON c.CD_ID = d.CD_ID
	LEFT JOIN COLUMNS_V2 e ON d.CD_ID = e.CD_ID
	LEFT JOIN (SELECT TBL_ID,GROUP_CONCAT(PKEY_NAME) AS PART_KEYS FROM PARTITION_KEYS  GROUP BY TBL_ID) f on t.TBL_ID = f.TBL_ID
	// where a. NAME = 'hive库名' 此处选择你需要的库
	order by 1,2,4
  • TBLS表存储Hive表信息
  • DBS表存储Hive库信息
  • TABLE_PARAMS表存储Hive表的一些参数信息
  • COLUMNS_V2表存储Hive表的字段信息
  • PARTITION_KEYS表存储表的分区字段
    至于这些表为什么这么关联,大家可以使用Navicat的逆向数据库到模型功能查看。
    在这里插入图片描述
    运行以上SQL可以得到以下结果:
    在这里插入图片描述

导出结果为JSON

Navicat有个很方便的功能,可以把查询结果导出为JSON。
在这里插入图片描述
点击下一步设置好JSON文件路径,再下一步指定编码。
在这里插入图片描述
最后点击开始,导出结果JSON。

通过Java代码读取JSON并生成md

打开JSON文件,JSON的格式为:

{
	"RECORDS":[
		{
		"SCHEMA_NAME":"hive_db",
		"TABLE_NAME":"hive_table",
		"TABLE_COMMENT":"",
		"COLUMN_ID":0,
		"COLUMN_NAME":"userid",
		"COLUMN_DATA_TYPE":"string",
		"PART_COLUMN":"log_date",
		"COMMENT":null
		},//内部一个大括号中的内容是Hive表的一列
		...,
		...
	]
}

我们需要定义两个对象来接收这个JSON文件数据

public class Record {
    private List<Column> records;

    public Record() {
    }

    public Record(List<Column> records) {
        this.records = records;
    }

    public List<Column> getRecords() {
        return records;
    }

    public void setRecords(List<Column> records) {
        this.records = records;
    }
}
public class Column {
    private String schemaName;//库名
    private String tableName;//表名
    private String tableComment;//表注释
    private String columnId;//表的列序号
    private String columnName;//表的列名
    private String columnDataType;//表的列的数据类型
    private String PartColumn;//表的分区字段
    private String comment;//表的列注释

    @Override
    public String toString() {//toString可根据喜好自定义输出字段
        return
                "|" + columnId +
                "|" + columnName +
                "|" + columnDataType +
                "|" + PartColumn +
                "|" + (comment == null?"":comment) +
                "|";
    }
    public String toStringWithNoPart() {
        return
                "|" + columnId +
                        "|" + columnName +
                        "|" + columnDataType +
                        "|" + (comment == null?"":comment) +
                        "|";
    }

    public String getTableComment() {
        return tableComment;
    }

    public void setTableComment(String tableComment) {
        this.tableComment = tableComment;
    }

    public String getSchemaName() {
        return schemaName;
    }

    public void setSchemaName(String schemaName) {
        this.schemaName = schemaName;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getColumnId() {
        return columnId;
    }

    public void setColumnId(String columnId) {
        this.columnId = columnId;
    }

    public String getColumnName() {
        return columnName;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    public String getColumnDataType() {
        return columnDataType;
    }

    public void setColumnDataType(String columnDataType) {
        this.columnDataType = columnDataType;
    }

    public String getPartColumn() {
        return PartColumn;
    }

    public void setPartColumn(String partColumn) {
        PartColumn = partColumn;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public Column() {
    }

    public Column(String schemaName, String tableName, String columnId, String columnName, String columnDataType, String partColumn, String comment) {
        this.schemaName = schemaName;
        this.tableName = tableName;
        this.columnId = columnId;
        this.columnName = columnName;
        this.columnDataType = columnDataType;
        PartColumn = partColumn;
        this.comment = comment;
    }
}

最后就是main方法将JSON文件内容转成Record对象,然后输出其中的Column。注意以下的markdown格式是Typora的语法,不同的markdown工具可能语法有一些差别。

public static void main(String[] args) {
		//FileReader来自Hutool工具包,可以在pom中导入,读取navicat生成的json文件
        FileReader fileReader = new FileReader("C:\\Users\\ut\\Desktop\\directory.json");
        String jsonStr = fileReader.readString();
        //JSONObject来自FastJson库,可以在pom中导入
        Record record = JSONObject.parseObject(jsonStr, Record.class);
        List<Column> columns = record.getRecords();
        for (Column column : columns) {//根据不同的样式输出列信息
            if("0".equals(column.getColumnId())){//根据列序号是否为0判断循环是否到一个新的表的列
                System.out.println("\n| 数据库名称 | 表名 | 字段序号 | 字段名 | 字段类型 | 分区字段 | 备注 |\n" +
                        "| ---- | ---- | ---- | ---- | ---- | ---- |");
            }
            System.out.println(column.toString());
        }
        try {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\Users\\Desktop\\directory.md")));//在指定目录输出
            for (Column column : columns) {
                if("0".equals(column.getColumnId())){
                    writer.write("## "+column.getSchemaName()+"."+column.getTableName()+"\n");
                    if(column.getTableComment() != null){
                        writer.write("**"+column.getTableComment()+"**");
                    }

                    if(column.getPartColumn() == null){
                        writer.write("\n| 字段序号 | 字段名 | 字段类型 | 备注 |\n" +
                                "| ---- | ---- | ---- | ---- |\n");
                    }else{
                        writer.write("\n| 字段序号 | 字段名 | 字段类型 | 分区字段 | 备注 |\n" +
                                "| ---- | ---- | ---- | ---- | ---- |\n");
                    }

                }
                if(column.getPartColumn() == null){
                    writer.write(column.toStringWithNoPart());
                    writer.newLine();
                }else{
                    writer.write(column.toString());
                    writer.newLine();
                }
            }
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
    }

运行main方法后,打开生成的markdown文件,渲染后如下:
在这里插入图片描述
以上操作就可以生成一个简易的数据字典。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值