The information_schema tables offer all kinds of useful metadata. Also all information about indexes are included in them, although they are split up among several tables.
I’ve built up a query that shows all the information about indexes, here it is:
SELECT a.table_schema, a.table_name, a.constraint_name, a.constraint_type, convert(group_concat(DISTINCT b.column_name ORDER BY b.ordinal_position SEPARATOR ', '), char) as column_list, b.referenced_table_name, b.referenced_column_name FROM information_schema.table_constraints a INNER JOIN information_schema.key_column_usage b ON a.constraint_name = b.constraint_name AND a.table_schema = b.table_schema AND a.table_name = b.table_name GROUP BY a.table_schema, a.table_name, a.constraint_name, a.constraint_type, b.referenced_table_name, b.referenced_column_name UNION SELECT table_schema, table_name, index_name as constraint_name, if(index_type='FULLTEXT', 'FULLTEXT', 'NON UNIQUE') as constraint_type, convert(group_concat(column_name ORDER BY seq_in_index separator ', '), char) as column_list, null as referenced_table_name, null as referenced_column_name FROM information_schema.statistics WHERE non_unique = 1 GROUP BY table_schema, table_name, constraint_name, constraint_type, referenced_table_name, referenced_column_name ORDER BY table_schema, table_name, constraint_name
Actually, at the moment I need this piece of information rather for PostgreSQL than for MySQL (for automatically renaming the index names according to coding standards), but I would have hated to do this without knowing how it works in MySQL. My PostgreSQL equivalent still misses the information for non unique indexes – the rest already works great. So here’s the PostgreSQL equivalent up to what I already have:
SELECT a.table_catalog, a.table_schema, a.table_name, a.constraint_name, a.constraint_type, array_to_string( array( SELECT column_name::varchar FROM information_schema.key_column_usage WHERE constraint_name = a.constraint_name ORDER BY ordinal_position ), ', ' ) as column_list, c.table_name, c.column_name FROM information_schema.table_constraints a INNER JOIN information_schema.key_column_usage b ON a.constraint_name = b.constraint_name LEFT JOIN information_schema.constraint_column_usage c ON a.constraint_name = c.constraint_name AND a.constraint_type = 'FOREIGN KEY' GROUP BY a.table_catalog, a.table_schema, a.table_name, a.constraint_name, a.constraint_type, c.table_name, c.column_name ORDER BY a.table_catalog, a.table_schema, a.table_name, a.constraint_name
Unfortunately, the statistics table doesn’t exist in PostgreSQL’s information_schema (is it an extension of MySQL or missing in PostgreSQL?), so I have to find another source for the non-unique index data. I’ll add the final query as comment to this article as soon as I’ve got it.