本文将分别介绍如何中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;