DB

数据库中元数据提取

MySQL、SQLServer、Oracle、DB2和Hive数据库中元数据提取

Posted by Arain on September 3, 2019

本文将分别介绍如何中MySQL、SQLServer、Oracle、DB2和Hive数据库的系统表中获取关于表、列、存储过程和函数相关的元数据元数据。本文编写时参考数据库版本如下:

数据库名称 版本
MySQL 5.7
SQLServer 2008
Oracle  
DB2 10.5.0
Hive  

什么是元数据

元数据(Metadata)是关于数据的数据。在数据仓库(Data Warehouse)系统中,元数据可以帮助数据仓库管理员和数据仓库的开发人员非常方便地找到他们所关心的数据;元数据是描述数据仓库内数据的结构和建立方法的数据,可将其按用途的不同分为两类:技术元数据(Technical Metadata)和业务元数据(Business Metadata)。

SCHEMA

在MySQL中基本认为schema和数据库相同

在ORACLE中schema和用户是同一个;

在DB2中schema不一定是用户,因为db2内部没有用户的概念,连接用户必须是操作系统用户.

MySQL

SELECT (select count(COLUMN_NAME) from information_schema.COLUMNS B where A.TABLE_SCHEMA = B.TABLE_SCHEMA and A.TABLE_NAME = B.TABLE_NAME) AS 'fields',A.* FROM INFORMATION_SCHEMA.TABLES A where A.table_schema = 'cubo_test'

information_schema

在 MySQL中, information_schema 是MySQL自带的一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等元数据。在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。

SCHEMATA

提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。

编号 列名 释义
1 CATALOG_NAME  
2 SCHEMA_NAME 数据库名称
3 DEFAULT_CHARACTER_SET_NAME 字符集
4 DEFAULT_COLLATION_NAME 排序规则
5 SQL_PATH  

TABLES

提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。

TABLE_CONSTRAINTS

描述了存在约束的表。以及表的约束类型。

COLUMNS

提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。

编号 列名 释义
1 TABLE_CATALOG  
2 TABLE_SCHEMA 数据库名称
3 TABLE_NAME 表名
4 COLUMN_NAME 列名
5 ORDINAL_POSITION  
6 COLUMN_DEFAULT 默认取值
7 IS_NULLABLE 取值是否可以为null
8 DATA_TYPE 数据类型
9 CHARACTER_MAXIMUM_LENGTH 字符类型的最大长度,不是字符类型时取值为null
10 CHARACTER_OCTET_LENGTH  
11 NUMERIC_PRECISION 数字类型的精度(长度)
12 NUMERIC_SCALE 数字类型的小数位数
13 DATETIME_PRECISION 事件类型精度
14 CHARACTER_SET_NAME 字符集
15 COLLATION_NAME 排序规则
16 COLUMN_TYPE 列类型,例如varchar(50)。DATA_TYPE和CHARACTER_MAXIMUM_LENGTH的整合
17 COLUMN_KEY 键,取值可为UNI、PRI、MUL和空字符串
18 EXTRA  
19 PRIVILEGES  
20 COLUMN_COMMENT 注释
21 GENERATION_EXPRESSION  

KEY_COLUMN_USAGE

描述了具有约束的键列。

STATISTICS

提供了关于表索引的信息。是show index from schemaname.tablename的结果取之此表。

USER_PRIVILEGES(用户权限)

给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。

SCHEMA_PRIVILEGES(数据库权限)

给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。是非标准表。

TABLE_PRIVILEGES(表权限)

给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。是非标准表。

COLUMN_PRIVILEGES(列权限)

给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。是非标准表。

CHARACTER_SETS(字符集)

提供了mysql实例可用字符集的信息。是SHOW CHARACTER SET结果集取之此表。

COLLATIONS

提供了关于各字符集的对照信息。

COLLATION_CHARACTER_SET_APPLICABILITY

指明了可用于校对的字符集。这些列等效于SHOW COLLATION的前两个显示字段。

ROUTINES

提供了关于存储子程序(存储程序和函数)的信息。此时,ROUTINES表不包含自定义函数(UDF)。名为“mysql.proc name”的列指明了对应于INFORMATION_SCHEMA.ROUTINES表的mysql.proc表列。

编号 列名 释义
1 SPECIFIC_NAME  
2 ROUTINE_CATALOG  
3 ROUTINE_SCHEMA  
4 ROUTINE_NAME  
5 ROUTINE_TYPE  
6 DATA_TYPE  
7 CHARACTER_MAXIMUM_LENGTH  
8 CHARACTER_OCTET_LENGTH  
9 NUMERIC_PRECISION  
10 NUMERIC_SCALE  
11 DATETIME_PRECISION  
12 CHARACTER_SET_NAME  
13 COLLATION_NAME  
14 DTD_IDENTIFIER  
15 ROUTINE_BODY  
16 ROUTINE_DEFINITION  
17 EXTERNAL_NAME  
18 EXTERNAL_LANGUAGE  
19 PARAMETER_STYLE  
20 IS_DETERMINISTIC  
21 SQL_DATA_ACCESS  
22 SQL_PATH  
23 SECURITY_TYPE  
24 CREATED  
25 LAST_ALTERED  
26 SQL_MODE  
27 ROUTINE_COMMENT  
28 DEFINER  
29 CHARACTER_SET_CLIENT  
30 COLLATION_CONNECTION  
31 DATABASE_COLLATION  

VIEWS

给出了关于数据库中的视图的信息。需要有show views权限,否则无法查看视图信息。

TRIGGERS

提供了关于触发程序的信息。必须有super权限才能查看该表。

SQLServer

官方文档:https://docs.microsoft.com/en-us/sql/sql-server/sql-server-technical-documentation?view=sql-server-2017

-- 系统表/视图
select * from syscomments;
select * from sysobjects;

select * from sys.objects;
select * from sys.schemas;
select * from sys.tables;
select * from sys.columns;
select * from sys.procedures;
select * from sys.indexes;
select * from sys.types;
select * from extended_properties;
-- 查看视图的定义
SELECT OBJECT_DEFINITION (OBJECT_ID('INFORMATION_SCHEMA.TABLES')) AS ObjectDefinition;   

-- 获取数据库的元数据
select * from INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME not in ('INFORMATION_SCHEMA', 'sys');


-- 获取数据表元数据
SELECT
	tb.name,
	tb.create_date,
	tb.modify_date,
	tb.type_desc,
	sch.name AS schema_name,
	idx.rows,
	CONVERT(varchar(200), com.value) AS comment,
	(SELECT COUNT(name) FROM sys.columns col WHERE col.object_id = tb.object_id) AS fields
FROM
	sys.tables tb
	LEFT JOIN sys.schemas sch ON tb.schema_id = sch.schema_id
	LEFT JOIN sysindexes idx ON tb.object_id = idx.id AND (idx.indid IN ( 0, 1 ))
	LEFT JOIN sys.extended_properties com ON tb.object_id = com.major_id and com.minor_id = '0'




-- 获取数据字段的元数据
-- 方案一:
SELECT
	sch.name AS schema_name,
    tb.name AS table_name,
    col.name AS column_name,
    col.max_length AS length,
    col.is_nullable AS nullable,
		col.scale AS scale,
    t.name AS type,
    (
			SELECT TOP 1 ind.is_primary_key
			FROM sys.index_columns ic 
			LEFT JOIN sys.indexes ind ON ic.object_id = ind.object_id AND ic.index_id= ind.index_id AND ind.name LIKE 'PK_%'
			WHERE ic.object_id = tb.object_id AND ic.column_id= col.column_id
    ) AS isPrimaryKey,
    com.value AS comment
FROM
    sys.tables tb
    INNER JOIN sys.columns col ON col.object_id = tb.object_id
	LEFT JOIN sys.schemas sch ON tb.schema_id = sch.schema_id
    LEFT JOIN sys.types t ON t.user_type_id = col.user_type_id
    LEFT JOIN sys.extended_properties com ON com.major_id = col.object_id
    AND com.minor_id = col.column_id
		
-- 方案二:
select * from INFORMATION_SCHEMA.COLUMNS





-- 获取函数/存储过程的元数据
SELECT
	obj.name,
	obj.type_desc,
	obj.create_date,
	obj.modify_date,
	syscom.ctext AS body, 
	sch.name AS schema_name,
	CONVERT(varchar(200), com.value) AS comment
FROM
	sys.objects obj
	LEFT JOIN syscomments syscom ON obj.object_id = syscom.id 
	LEFT JOIN sys.schemas sch ON obj.schema_id = sch.schema_id
	LEFT JOIN sys.extended_properties com ON obj.object_id = com.major_id
WHERE	obj.type IN ('P','FN');

Oracle

-- DBA是只有DBA权限的用户才能查询,内容包含了系统全部;
-- ALL是普通用户可以查询,内容包含了该用户所能访问的部分;
-- User是普通用户可以查询,内容包含了该用户是所有者的部分;
-- V$是数据字典动态视图,显示系统当前的状态。它的值在随时都可能发生变化。
select * from all_users;
select * from all_tables where TABLESPACE_NAME not in('SYSTEM', 'SYSAUX');
select * from all_tab_comments;
select * from all_tab_cols;
select * from all_col_comments;
select * from all_source;

select * from user_tables;
select * from user_tab_comments; 
select * from user_tab_cols;
select * from user_col_comments;

-- 获取数据库元数据
select * from all_users;


-- 获取数据表元数据
SELECT
	tab.TABLE_NAME, tab.LAST_ANALYZED, tab.NUM_ROWS,
	(select count(*) from user_tab_columns where table_name=tab.TABLE_NAME) as fields,
	com.TABLE_TYPE,
	com.COMMENTS
FROM
	user_tables tab
	LEFT JOIN user_tab_comments com ON tab.TABLE_NAME = com.TABLE_NAME
	
	
-- 获取表字段元数据
SELECT
	col.*,
	com.COMMENTS 
FROM
	user_tab_cols col
	LEFT JOIN user_col_comments com ON col.TABLE_NAME = com.TABLE_NAME AND col.COLUMN_NAME = com.COLUMN_NAME;
	
	
-- 	获取函数元数据
SELECT
	* 
FROM
	user_source 
WHERE
	TYPE IN ( 'PROCEDURE', 'FUNCTION' )
	ORDER BY NAME ASC, type asc, line asc

DB2

-- SYSIBM: 基本系统编目,不建议直接访问
-- SYSCAT: 默认授权给Public组.只读编目视图,一般通过这个来获取编目信息
-- SYSSTAT: 可更新编目视图,会影响优化器的优化策略
-- SYSFUN: 用户定义函数
-- SYSPROC: 存放一组系统的存储过程

-- 获取系统用户的视图
SELECT * FROM SYSIBM.SYSTABLES WHERE NAME like 'USER_%';

-- 获取Schema元数据
select SCHEMANAME,OWNER from syscat.schemata;


-- 获取数据表元数据
SELECT
  TABSCHEMA, TABNAME, TYPE, CREATE_TIME, ALTER_TIME, COLCOUNT, CARD, REMARKS
FROM
  syscat.tables
where OWNER = CURRENT USER;


-- 获取表字段元数据
SELECT
  COL.TABSCHEMA AS TABLE_SCHEMA,
  COL.TABNAME AS TABLE_NAME,
  COL.COLNAME AS COLUMN_NAME,
  CAST(COL.COLNO + 1 AS SMALLINT) AS COLUMN_ID,
  COL.DEFAULT AS DATA_DEFAULT,
  COL.NUMNULLS AS NULLABLE,
  COL.REMARKS AS COMMENTS,
  COL.TYPENAME AS DATA_TYPE,
  CASE COL.TYPENAME
    WHEN 'GRAPHIC'
    THEN COL.LENGTH*2
    WHEN 'VARGRAPHIC'
    THEN COL.LENGTH*2
    WHEN 'LONG VARGRAPHIC'
    THEN COL.LENGTH*2
    WHEN 'DBCLOB'
    THEN COL.LENGTH*2
    ELSE COL.LENGTH
  END AS DATA_LENGTH,
  CASE COL.TYPENAME
    WHEN 'DECIMAL'
    THEN COL.LENGTH
  END AS DATA_PRECISION,
  CASE COL.TYPENAME
    WHEN 'CHAR'
    THEN COL.LENGTH
    WHEN 'VARCHAR'
    THEN COL.LENGTH
    WHEN 'LONG VARCHAR'
    THEN COL.LENGTH
  END AS CHAR_COL_DECL_LENGTH,
  COL.SCALE AS DATA_SCALE
FROM
  SYSCAT.COLUMNS AS COL,
  SYSCAT.TABLES AS TAB
WHERE
  COL.TABSCHEMA = TAB.TABSCHEMA
  AND TAB.TABNAME = COL.TABNAME
  AND TAB.TYPE NOT IN('A', 'V', 'W', 'N');


-- 	获取函数元数据
select
  ROUTINESCHEMA, SPECIFICNAME, ROUTINEMODULENAME, ROUTINETYPE, TEXT, OWNER, CREATE_TIME, ALTER_TIME
from syscat.routines
where ROUTINETYPE in ('F', 'P') and text IS NOT NULL and OWNER = CURRENT USER;

Hive