查找具有与给定模式匹配的列名称的表

时间:2012-01-16 08:21:45

标签: mysql sql postgresql relational-database introspection

这可能听起来有点不太现实,但我最近不得不研究远程维护的系统的数据库结构,当我想找到链接到的所有列时,我发现有一些情况。一个给定的表(参见,原始开发人员没有创建显式关系,而是在列名中编码关系!)。

例如,假设所有引用列parent.parent的列都具有table.somefield_parent形式作为记录两个字段之间关系的方法,我如何找到所有这些关系(以及涉及的表) )使用标准的SQL命令/内置函数吗?

欢迎使用MySQL或PostgreSQL的任何解决方案。

注意:

  • 我不是在寻找数据中的模式,而是在元数据中。
  • 我知道我可以转储db结构并在那里搜索结果,但是我不想离开db-shell来找到这些关系(假设我正在使用psql,并且不想出口)

3 个答案:

答案 0 :(得分:7)

尝试查询information_schema.columns视图。它适用于MySQL,但我没有在Postgres中尝试过。 information_schema模式是ANSI SQL标准的一部分,因此Postgres很可能也会拥有它。

information_schema中的其他观点包括information_schema.tables,这也很有用

答案 1 :(得分:1)

PostgreSQL 中,您可以查询系统目录表。

您还可以查询information_schema,它包含提供标准SQL显示信息方式的视图。但是,查询系统目录通常要快得多。

要查找一个特定parent列的子项:

SELECT n.nspname AS schema_name
     , c.relname AS table_name
     , a.attname AS column_name
FROM   pg_catalog.pg_attribute a
JOIN   pg_catalog.pg_class c ON c.oid = a.attrelid
JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE  a.attname ~~ E'%\\_parent'
AND    NOT a.attisdropped
AND    c.relkind = 'r'
AND    nspname !~~ E'pg\\_%';

根据说明找到所有相关列:

SELECT n.nspname AS parrent_schema
     , c.relname AS parrent_table
     , a.attname AS parrent_column
     , n1.nspname AS child_schema
     , c1.relname AS child_table
     , a1.attname AS child_column
FROM   pg_catalog.pg_attribute a
JOIN   pg_catalog.pg_class c ON c.oid = a.attrelid
JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
JOIN   pg_catalog.pg_attribute a1 ON a.attname = substring(a1.attname, '_(.*?)$')
JOIN   pg_catalog.pg_class c1 ON c1.oid = a1.attrelid
JOIN   pg_catalog.pg_namespace n1 ON n1.oid = c1.relnamespace
WHERE  c.relkind = 'r'
AND    c1.relkind = 'r'
AND    n.nspname !~~ E'pg\\_%'
AND    n1.nspname !~~ E'pg\\_%'
AND    NOT a.attisdropped
AND    NOT a1.attisdropped
-- AND    n.nspname = 'public'   -- to narrow it down to a specific schema
-- AND    n1.nspname = 'public'   -- to narrow it down to a specific schema
ORDER  BY 1,2,3,4,5,6

这假设parrent列的名称中没有_ 关键元素是连接条件:

a.attname = substring(a1.attname, '_(.*?)$')

答案 2 :(得分:0)

如果您使用MySQL,则可以使用数据库information_schema。此数据库包含该服务器上数据库的所有元数据。据我所知,每个数据库用户都必须能够访问该数据库。