Найти таблицу с именем столбца, соответствующим заданному шаблону - PullRequest
3 голосов
/ 16 января 2012

Это может показаться немного нереалистичным, но мне недавно пришлось изучить структуру базы данных системы, которую я поддерживаю удаленно, и мне показалось, что были некоторые случаи, когда я хотел найти все столбцы, которые были связаны с заданной таблицы (см., оригинальные разработчики не создавали явных отношений, но вместо этого имели отношения, закодированные в именах столбцов!).

Например, если предположить, что все столбцы, ссылающиеся на столбец parent.parent, имеют форму table.somefield_parent в качестве средства документирования отношений между двумя полями, как мне найти все такие отношения (и соответствующие таблицы), используя, скажем, стандартные команды SQL / встроенные функции?

Любые решения для MySQL или PostgreSQL приветствуются.

ПРИМЕЧАНИЕ:

  • я ищу не шаблоны в данных, а в метаданных.
  • Я знаю, что могу вывести структуру db и искать там результаты, но я не хочу выходить из db-shell, чтобы найти эти отношения (предположим, я работаю в скажем psql и не хочу выход)

Ответы [ 3 ]

7 голосов
/ 16 января 2012

Попробуйте запросить представление information_schema.columns. Это работает в MySQL, но я не пробовал это в Postgres. Схема information_schema является частью стандарта ANSI SQL, поэтому вполне вероятно, что Postgres будет иметь его.

Другие виды в information_schema включают information_schema.tables, что также полезно

1 голос
/ 16 января 2012

В PostgreSQL вы можете запросить таблицы системного каталога.

Вы также можете запросить информационную схему, которая состоит из представлений, предоставляющих стандартный способ отображения информации в 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, '_(.*?)$')
0 голосов
/ 16 января 2012

Если вы используете MySQL, вы можете использовать базу данных information_schema для этого. Эта база данных содержит все метаданные для баз данных на этом сервере. Насколько я знаю, каждый пользователь базы данных должен иметь доступ к этой базе данных.

...