PostgreSQL教程FG134-PG信息模式:核心视图与数据字典查询
本文档风哥主要介绍PostgreSQL的信息模式(Information Schema),包括核心视图和数据字典查询,风哥教程参考PostgreSQL官方文档,适合DBA和开发人员在学习和测试中使用。
Part01-基础概念与理论知识
1.1 信息模式概述
信息模式(Information Schema)是SQL标准定义的一组视图,用于提供数据库元数据的访问接口。PostgreSQL实现了SQL标准的信息模式,位于information_schema模式中。更多视频教程www.fgedu.net.cn
from oracle:www.itpux.com
- 标准化:符合SQL标准,跨数据库兼容
- 只读:信息模式视图是只读的
- 实时:反映数据库的当前状态
- 安全:只显示用户有权限访问的对象
1.2 核心视图介绍
信息模式的核心视图:
— 1. 模式相关视图
— schemata: 显示所有模式
SELECT schema_name FROM information_schema.schemata;
— 2. 表相关视图
— tables: 显示所有表
SELECT table_schema, table_name, table_type
FROM information_schema.tables;
— 3. 列相关视图
— columns: 显示所有列
SELECT table_schema, table_name, column_name, data_type
FROM information_schema.columns;
— 4. 约束相关视图
— table_constraints: 显示所有表约束
SELECT constraint_schema, constraint_name, table_name, constraint_type
FROM information_schema.table_constraints;
— 5. 索引相关视图(PostgreSQL特有)
— 信息模式不包含索引视图,需要使用系统目录
— 6. 权限相关视图
— table_privileges: 显示表权限
SELECT grantee, table_schema, table_name, privilege_type
FROM information_schema.table_privileges;
1.3 数据字典概念
数据字典是描述数据库元数据的信息集合,包括:
- 结构信息:表、列、索引、约束等结构定义
- 关系信息:表之间的关系、外键关系
- 权限信息:用户权限、角色关系
- 统计信息:表大小、行数等统计信息
Part02-生产环境规划与建议
2.1 信息模式设计
信息模式的设计原则:
— 1. 标准化设计
— 信息模式遵循SQL标准,提供统一的元数据访问接口
— 2. 安全性设计
— 信息模式只显示当前用户有权限访问的对象
— 3. 实时性设计
— 信息模式视图基于系统目录实时生成
— 4. 扩展性设计
— 可以在信息模式基础上创建自定义视图
— 创建自定义元数据视图示例
CREATE OR REPLACE VIEW fgedu_table_info AS
SELECT
t.table_schema,
t.table_name,
t.table_type,
(SELECT COUNT(*) FROM information_schema.columns c
WHERE c.table_schema = t.table_schema AND c.table_name = t.table_name) as column_count,
(SELECT COUNT(*) FROM information_schema.table_constraints tc
WHERE tc.table_schema = t.table_schema AND tc.table_name = t.table_name) as constraint_count
FROM information_schema.tables t
WHERE t.table_schema NOT IN (‘pg_catalog’, ‘information_schema’);
2.2 查询优化
信息模式查询优化建议:
- 添加过滤条件:使用WHERE子句减少返回的数据量
- 限制返回列:只选择需要的列
- 使用索引:信息模式视图基于系统目录,会自动使用索引
- 缓存结果:对于不经常变化的元数据,可以缓存查询结果
— 优化前:查询所有列
SELECT * FROM information_schema.columns;
— 优化后:只查询需要的列,并添加过滤条件
SELECT column_name, data_type, character_maximum_length
FROM information_schema.columns
WHERE table_schema = ‘public’
AND table_name = ‘fgedu_employees’;
2.3 安全考虑
信息模式的安全考虑:
- 权限控制:信息模式只显示用户有权限的对象
- 敏感信息:避免在信息模式中暴露敏感信息
- 审计日志:记录对敏感元数据的访问
Part03-生产环境项目实施方案
3.1 模式查询
3.1.1 查询所有模式
— 1. 查询所有模式
SELECT schema_name, schema_owner
FROM information_schema.schemata
ORDER BY schema_name;
— 返回结果示例:
— schema_name | schema_owner
— —————+—————
— information_schema| pgsql — pg_catalog | pgsql — public | pgsql — fgedu_schema | fgedu_fgedu
— 2. 查询用户定义的模式(排除系统模式)
SELECT schema_name, schema_owner
FROM information_schema.schemata
WHERE schema_name NOT IN (‘pg_catalog’, ‘information_schema’, ‘pg_toast’)
AND schema_name NOT LIKE ‘pg_temp%’
AND schema_name NOT LIKE ‘pg_toast_temp%’
ORDER BY schema_name;
— 3. 查询特定用户的模式
SELECT schema_name
FROM information_schema.schemata
WHERE schema_owner = ‘fgedu_fgedu’
ORDER BY schema_name;
— 4. 查询模式中的表数量
SELECT
s.schema_name,
COUNT(t.table_name) as table_count
FROM information_schema.schemata s
LEFT JOIN information_schema.tables t
ON s.schema_name = t.table_schema
WHERE s.schema_name NOT IN (‘pg_catalog’, ‘information_schema’)
GROUP BY s.schema_name
ORDER BY table_count DESC;
3.2 表查询
3.2.1 查询所有表
— 1. 查询所有表
SELECT table_schema, table_name, table_type
FROM information_schema.tables
WHERE table_schema NOT IN (‘pg_catalog’, ‘information_schema’)
ORDER BY table_schema, table_name;
— 返回结果示例:
— table_schema | table_name | table_type
— ————-+—————–+———–
— public | fgedu_employees | BASE TABLE
— public | fgedu_departments| BASE TABLE
— public | employee_view | VIEW
— 2. 查询特定模式的表
SELECT table_name, table_type
FROM information_schema.tables
WHERE table_schema = ‘public’
ORDER BY table_name;
— 3. 查询表的基本信息
SELECT
t.table_schema,
t.table_name,
t.table_type,
pg_size_pretty(pg_total_relation_size(t.table_schema || ‘.’ || t.table_name)) as total_size
FROM information_schema.tables t
WHERE t.table_schema = ‘public’
ORDER BY pg_total_relation_size(t.table_schema || ‘.’ || t.table_name) DESC;
— 4. 查询表的行数(近似值)
SELECT
t.table_schema,
t.table_name,
(SELECT reltuples::BIGINT FROM pg_class WHERE relname = t.table_name) as row_count
FROM information_schema.tables t
WHERE t.table_schema = ‘public’
AND t.table_type = ‘BASE TABLE’
ORDER BY row_count DESC;
3.3 列查询
3.3.1 查询所有列
— 1. 查询表的所有列
SELECT
column_name,
data_type,
character_maximum_length,
numeric_precision,
numeric_scale,
is_nullable,
column_default
FROM information_schema.columns
WHERE table_schema = ‘public’
AND table_name = ‘fgedu_employees’
ORDER BY ordinal_position;
— 返回结果示例:
— column_name | data_type | character_maximum_length | is_nullable | column_default
— ————+———–+————————-+————-+——————
— id | integer | | NO | nextval(‘…’)
— name | character | 100 | NO |
— age | integer | | NO |
— department | character | 100 | YES |
— 2. 查询特定类型的列
SELECT table_schema, table_name, column_name, data_type
FROM information_schema.columns
WHERE data_type = ‘character varying’
AND table_schema = ‘public’
ORDER BY table_name, ordinal_position;
— 3. 查询可空列
SELECT table_schema, table_name, column_name, data_type
FROM information_schema.columns
WHERE is_nullable = ‘YES’
AND table_schema = ‘public’
ORDER BY table_name, ordinal_position;
— 4. 查询有默认值的列
SELECT table_schema, table_name, column_name, column_default
FROM information_schema.columns
WHERE column_default IS NOT NULL
AND table_schema = ‘public’
ORDER BY table_name, ordinal_position;
— 5. 查询列统计信息
SELECT
table_name,
COUNT(*) as column_count,
COUNT(CASE WHEN is_nullable = ‘NO’ THEN 1 END) as not_null_count,
COUNT(CASE WHEN column_default IS NOT NULL THEN 1 END) as default_count
FROM information_schema.columns
WHERE table_schema = ‘public’
GROUP BY table_name
ORDER BY column_count DESC;
3.4 约束查询
3.4.1 查询所有约束
— 1. 查询表的所有约束
SELECT
constraint_name,
constraint_type,
table_name
FROM information_schema.table_constraints
WHERE table_schema = ‘public’
AND table_name = ‘fgedu_employees’
ORDER BY constraint_type, constraint_name;
— 返回结果示例:
— constraint_name | constraint_type | table_name
— ———————+—————–+—————
— fgedu_employees_pkey | PRIMARY KEY | fgedu_employees
— fgedu_employees_name_key| UNIQUE | fgedu_employees
— fgedu_employees_age_check| CHECK | fgedu_employees
— 2. 查询主键约束
SELECT
tc.table_name,
tc.constraint_name,
kcu.column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.constraint_type = ‘PRIMARY KEY’
AND tc.table_schema = ‘public’
ORDER BY tc.table_name;
— 3. 查询外键约束
SELECT
tc.table_name,
tc.constraint_name,
kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = ‘FOREIGN KEY’
AND tc.table_schema = ‘public’
ORDER BY tc.table_name;
— 4. 查询约束统计
SELECT
constraint_type,
COUNT(*) as constraint_count
FROM information_schema.table_constraints
WHERE table_schema = ‘public’
GROUP BY constraint_type
ORDER BY constraint_count DESC;
Part04-生产案例与实战讲解
4.1 常用查询
4.1.1 数据库结构查询
— 1. 查询数据库中所有表及其列数
SELECT
t.table_name,
COUNT(c.column_name) as column_count
FROM information_schema.tables t
LEFT JOIN information_schema.columns c
ON t.table_name = c.table_name AND t.table_schema = c.table_schema
WHERE t.table_schema = ‘public’
AND t.table_type = ‘BASE TABLE’
GROUP BY t.table_name
ORDER BY column_count DESC;
— 2. 查询所有外键关系
SELECT
tc.table_name as table_name,
kcu.column_name as column_name,
ccu.table_name as foreign_table_name,
ccu.column_name as foreign_column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = ‘FOREIGN KEY’
AND tc.table_schema = ‘public’
ORDER BY tc.table_name;
— 3. 查询所有索引(使用系统目录)
SELECT
schemaname,
tablename,
indexname,
indexdef
FROM pg_indexes
WHERE schemaname = ‘public’
ORDER BY tablename, indexname;
— 4. 查询表大小(使用系统函数)
SELECT
relname as table_name,
pg_size_pretty(pg_total_relation_size(oid)) as total_size,
pg_size_pretty(pg_relation_size(oid)) as table_size,
pg_size_pretty(pg_indexes_size(oid)) as index_size
FROM pg_class
WHERE relkind = ‘r’
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = ‘public’)
ORDER BY pg_total_relation_size(oid) DESC;
4.2 高级查询
4.2.1 复杂元数据查询
— 1. 生成表结构文档
SELECT
c.table_name,
c.column_name,
c.data_type ||
CASE
WHEN c.character_maximum_length IS NOT NULL
THEN ‘(‘ || c.character_maximum_length || ‘)’
WHEN c.numeric_precision IS NOT NULL
THEN ‘(‘ || c.numeric_precision || ‘,’ || COALESCE(c.numeric_scale, 0) || ‘)’
ELSE ”
END as data_type,
CASE WHEN c.is_nullable = ‘NO’ THEN ‘NOT NULL’ ELSE ‘NULL’ END as nullable,
COALESCE(c.column_default, ”) as default_value,
COALESCE(
(SELECT ‘PK’ FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.constraint_type = ‘PRIMARY KEY’
AND kcu.table_name = c.table_name
AND kcu.column_name = c.column_name
LIMIT 1),
”
) as key_type
FROM information_schema.columns c
WHERE c.table_schema = ‘public’
ORDER BY c.table_name, c.ordinal_position;
— 2. 查询无主键的表
SELECT t.table_name
FROM information_schema.tables t
LEFT JOIN information_schema.table_constraints tc
ON t.table_name = tc.table_name
AND tc.constraint_type = ‘PRIMARY KEY’
WHERE t.table_schema = ‘public’
AND t.table_type = ‘BASE TABLE’
AND tc.constraint_name IS NULL;
— 3. 查询无索引的表
SELECT t.table_name
FROM information_schema.tables t
LEFT JOIN pg_indexes pi
ON t.table_name = pi.tablename
WHERE t.table_schema = ‘public’
AND t.table_type = ‘BASE TABLE’
AND pi.indexname IS NULL;
— 4. 查询重复索引
SELECT
tablename,
indexdef,
COUNT(*) as duplicate_count
FROM pg_indexes
WHERE schemaname = ‘public’
GROUP BY tablename, indexdef
HAVING COUNT(*) > 1;
4.3 查询实战案例
4.3.1 数据库审计查询
— 1. 查询所有用户及其权限
SELECT
grantee,
COUNT(DISTINCT table_name) as table_count,
STRING_AGG(DISTINCT privilege_type, ‘, ‘) as privileges
FROM information_schema.table_privileges
WHERE grantee NOT LIKE ‘pg_%’
AND grantee NOT IN (‘postgres’, ‘PUBLIC’)
GROUP BY grantee;
— 2. 查询没有注释的表
SELECT table_name
FROM information_schema.tables
WHERE table_schema = ‘public’
AND table_type = ‘BASE TABLE’
AND table_name NOT IN (
SELECT objname FROM pg_description
JOIN pg_class ON pg_description.objoid = pg_class.oid
WHERE objsubid = 0
);
— 3. 查询大表(超过100万行)
SELECT
relname as table_name,
reltuples::BIGINT as row_count
FROM pg_class
WHERE relkind = ‘r’
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = ‘public’)
AND reltuples > 1000000
ORDER BY reltuples DESC;
— 4. 生成数据库文档
SELECT
‘CREATE TABLE fgedu_’ || t.table_name || ‘ (‘ as create_statement
FROM information_schema.tables t
WHERE t.table_schema = ‘public’
AND t.table_type = ‘BASE TABLE’
UNION ALL
SELECT
‘ ‘ || c.column_name || ‘ ‘ || c.data_type ||
CASE WHEN c.is_nullable = ‘NO’ THEN ‘ NOT NULL’ ELSE ” END || ‘,’
FROM information_schema.columns c
WHERE c.table_schema = ‘public’
ORDER BY 1;
Part05-风哥经验总结与分享
5.1 查询技巧
信息模式查询技巧:
- 使用过滤条件:始终使用WHERE子句过滤数据
- 限制返回列:只选择需要的列
- 结合系统目录:信息模式与系统目录结合使用
- 创建自定义视图:创建常用的元数据查询视图
- 缓存结果:对于不经常变化的元数据,可以缓存结果
5.2 自动化脚本
# 信息模式查询自动化脚本
# from:www.itpux.com.qq113257174.wx:itpux-com
# from:www.itpux.com.qq113257174.wx:itpux-com
# from:www.itpux.com.qq113257174.wx:itpux-com
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# web: `http://www.fgedu.net.cn`
# web: `http://www.fgedu.net.cn`
# web: http://www.fgedu.net.cn
DB_NAME=”fgedudb”
DB_USER=”pgsql”
OUTPUT_DIR=”/tmp/db_metadata”
mkdir -p $OUTPUT_DIR
# 1. 导出表结构
echo “导出表结构…”
psql -U $DB_USER -d $DB_NAME -c ”
COPY (
SELECT
table_name,
column_name,
data_type,
is_nullable,
column_default
FROM information_schema.columns
WHERE table_schema = ‘public’
ORDER BY table_name, ordinal_position
) TO ‘$OUTPUT_DIR/columns.csv’ WITH CSV HEADER;
”
# 2. 导出约束信息
echo “导出约束信息…”
psql -U $DB_USER -d $DB_NAME -c ”
COPY (
SELECT
table_name,
constraint_name,
constraint_type
FROM information_schema.table_constraints
WHERE table_schema = ‘public’
ORDER BY table_name, constraint_type
) TO ‘$OUTPUT_DIR/constraints.csv’ WITH CSV HEADER;
”
# 3. 生成数据库文档
echo “生成数据库文档…”
psql -U $DB_USER -d $DB_NAME -c ”
SELECT
‘表名: ‘ || table_name || E’\n’ ||
‘列数: ‘ || (SELECT COUNT(*) FROM information_schema.columns c
WHERE c.table_name = t.table_name)::text || E’\n’ ||
‘约束数: ‘ || (SELECT COUNT(*) FROM information_schema.table_constraints tc
WHERE tc.table_name = t.table_name)::text || E’\n’
FROM information_schema.tables t
WHERE table_schema = ‘public’
AND table_type = ‘BASE TABLE’
” > $OUTPUT_DIR/fgedudb_documentation.txt
echo “元数据导出完成,文件保存在: $OUTPUT_DIR”
5.3 资源与工具
信息模式相关资源与工具:
- PostgreSQL官方文档:https://www.postgresql.org/docs/current/information-schema.html
- pgAdmin:图形化查看数据库结构
- psql:命令行查询元数据
- SchemaSpy:生成数据库文档
- DbVisualizer:数据库可视化工具
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
