#MySQL Metadata
#Overview
Metadata is data about data. MySQL provides extensive metadata through system databases and information schema tables, allowing you to query database structure, table definitions, indexes, and more.
#Metadata Sources
- information_schema: Metadata about all databases
- mysql: System database with grants
- performance_schema: Performance metrics
- sys: Views on performance_schema
- SHOW Commands: Display metadata directly
#information_schema Database
#Overview
-- Access information_schema
USE information_schema;
-- List all information_schema tables
SHOW TABLES;
-- Key information_schema tables
-- SCHEMATA: Database information
-- TABLES: Table information
-- COLUMNS: Column information
-- KEY_COLUMN_USAGE: Key usage
-- STATISTICS: Index information
-- USER_PRIVILEGES: User privileges
-- TABLE_CONSTRAINTS: Constraints#Database Metadata
-- List all databases
SELECT schema_name AS database_name
FROM information_schema.SCHEMATA
WHERE schema_name NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');
-- Database character sets
SELECT
schema_name,
default_character_set_name,
default_collation_name
FROM information_schema.SCHEMATA;
-- Database sizes
SELECT
table_schema AS database_name,
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.TABLES
GROUP BY table_schema
ORDER BY size_mb DESC;#Table Metadata
-- List tables in current database
SELECT
table_name,
table_type,
engine,
row_format,
table_rows,
avg_row_length,
data_length,
index_length,
auto_increment,
create_time,
update_time,
check_time,
table_collation
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
ORDER BY table_name;
-- Filter by engine
SELECT table_name
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
AND engine = 'InnoDB';
-- Filter by table type
SELECT table_name, table_type
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
AND table_type = 'BASE TABLE';#Column Metadata
-- Get table columns
SELECT
column_name,
ordinal_position,
column_default,
is_nullable,
data_type,
character_maximum_length,
numeric_precision,
numeric_scale,
character_set_name,
collation_name,
column_type,
column_key,
extra
FROM information_schema.COLUMNS
WHERE table_schema = DATABASE()
AND table_name = 'users'
ORDER BY ordinal_position;
-- Find nullable columns
SELECT table_name, column_name, is_nullable
FROM information_schema.COLUMNS
WHERE table_schema = DATABASE()
AND is_nullable = 'YES';
-- Find auto increment columns
SELECT table_name, column_name
FROM information_schema.COLUMNS
WHERE table_schema = DATABASE()
AND extra LIKE '%auto_increment%';#Index Metadata
-- List indexes
SELECT
index_name,
column_name,
seq_in_index,
cardinality,
index_type,
is_unique
FROM information_schema.STATISTICS
WHERE table_schema = DATABASE()
AND table_name = 'users'
ORDER BY index_name, seq_in_index;
-- Index details
SELECT
s.table_name,
s.index_name,
s.column_name,
s.cardinality,
t.table_rows,
ROUND(s.cardinality / t.table_rows * 100, 2) AS selectivity_pct
FROM information_schema.STATISTICS s
JOIN information_schema.TABLES t
ON s.table_name = t.table_name
AND s.table_schema = t.table_schema
WHERE s.table_schema = DATABASE()
ORDER BY s.index_name, s.seq_in_index;
-- Unique indexes
SELECT DISTINCT index_name, column_name
FROM information_schema.STATISTICS
WHERE table_schema = DATABASE()
AND table_name = 'users'
AND non_unique = 0;#SHOW Commands
#Database SHOW Commands
-- Show databases
SHOW DATABASES;
SHOW DATABASES LIKE 'myapp%';
SHOW DATABASES WHERE schema_name LIKE '%dev%';
-- Show current database
SELECT DATABASE();
-- Show character sets
SHOW CHARACTER SET;
SHOW CHARACTER SET LIKE 'utf8%';
-- Show collations
SHOW COLLATION;
SHOW COLLATION LIKE 'utf8mb4%';
-- Show engines
SHOW ENGINES;
SHOW STORAGE ENGINES;#Table SHOW Commands
-- Show tables
SHOW TABLES;
SHOW TABLES FROM database_name;
SHOW TABLES LIKE 'user%';
SHOW FULL TABLES; -- Includes table type
-- Show table structure
DESCRIBE table_name;
DESC table_name;
EXPLAIN table_name;
SHOW COLUMNS FROM table_name;
SHOW FIELDS FROM table_name;
-- Show create statement
SHOW CREATE TABLE table_name;
SHOW CREATE TABLE table_name\G;
-- Show table status
SHOW TABLE STATUS;
SHOW TABLE STATUS LIKE 'users%';
SHOW TABLE STATUS WHERE name = 'users';#Index SHOW Commands
-- Show indexes
SHOW INDEX FROM table_name;
SHOW INDEXES FROM table_name;
SHOW KEYS FROM table_name;
-- Show index details
SHOW INDEX FROM users\G;#Other SHOW Commands
-- Show users
SHOW GRANTS FOR CURRENT_USER();
SHOW GRANTS FOR 'username'@'hostname';
-- Show privileges
SHOW PRIVILEGES;
-- Show processes
SHOW PROCESSLIST;
SHOW FULL PROCESSLIST;
-- Show variables
SHOW VARIABLES;
SHOW VARIABLES LIKE 'innodb%';
SHOW GLOBAL VARIABLES LIKE 'max%';
-- Show status
SHOW STATUS;
SHOW STATUS LIKE 'Connections%';
SHOW GLOBAL STATUS;
-- Show engines
SHOW ENGINES;#MySQL System Database
#mysql Database
-- Use mysql database
USE mysql;
-- User information
SELECT user, host FROM mysql.user;
-- Database privileges
SELECT * FROM mysql.db;
-- Table privileges
SELECT * FROM mysql.tables_priv;
-- Column privileges
SELECT * FROM mysql.columns_priv;
-- Proxies
SELECT * FROM mysql.proxies_priv;#User Metadata
-- List all users
SELECT user, host FROM mysql.user;
-- User with all hosts
SELECT DISTINCT user FROM mysql.user;
-- User privileges
SELECT * FROM mysql.user WHERE user = 'root';
-- Password hashes
SELECT user, host, plugin, authentication_string
FROM mysql.user;#Performance Metadata
#performance_schema Database
-- Use performance_schema
USE performance_schema;
-- Show available instruments
SELECT * FROM setup_instruments LIMIT 10;
-- Enable instruments
UPDATE setup_instruments
SET enabled = 'YES', timed = 'YES'
WHERE name LIKE 'statement/%';
-- Show consumers
SELECT * FROM setup_consumers;#Performance Queries
-- Wait events
SELECT * FROM events_waits_current
LIMIT 10;
-- Statement performance
SELECT
digest_text AS statement,
count_star AS exec_count,
avg_timer_wait / 1000000000000 AS avg_wait_ms
FROM events_statements_summary_by_digest
ORDER BY sum_timer_wait DESC
LIMIT 10;
-- Table I/O
SELECT
object_name AS table_name,
count_read,
count_write,
sum_timer_read / 1000000000000 AS read_time_ms
FROM file_summary_by_instance
WHERE object_name IS NOT NULL
ORDER BY sum_timer_read DESC
LIMIT 10;#sys Database
-- Use sys database (MySQL 5.7+)
USE sys;
-- User statistics
SELECT * FROM sys.user_summary;
-- Table statistics
SELECT * FROM sys.schema_unused_tables;
SELECT * FROM sys.schema_redundant_indexes;
-- Wait analysis
SELECT * FROM sys.wait_classes_global_by_latency;
SELECT * FROM sys.waits_global_by_latency;
-- Memory usage
SELECT * FROM sys.memory_global_by_current_bytes;#Metadata Queries
#Search for Tables
-- Find tables with specific column
SELECT table_name
FROM information_schema.COLUMNS
WHERE table_schema = DATABASE()
AND column_name = 'user_id';
-- Find tables without primary key
SELECT t.table_name
FROM information_schema.TABLES t
LEFT JOIN information_schema.KEY_COLUMN_USAGE k
ON t.table_name = k.table_name
AND t.table_schema = k.table_schema
WHERE t.table_schema = DATABASE()
AND k.constraint_name = 'PRIMARY';
-- Find tables with specific engine
SELECT table_name
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
AND engine = 'InnoDB';#Search for Columns
-- Find all columns named 'email'
SELECT
table_name,
column_name,
data_type
FROM information_schema.COLUMNS
WHERE table_schema = DATABASE()
AND column_name = 'email';
-- Find all VARCHAR columns
SELECT table_name, column_name, character_maximum_length
FROM information_schema.COLUMNS
WHERE table_schema = DATABASE()
AND data_type = 'varchar';
-- Find all datetime columns
SELECT table_name, column_name
FROM information_schema.COLUMNS
WHERE table_schema = DATABASE()
AND data_type IN ('date', 'datetime', 'timestamp');#Search for Constraints
-- Find foreign keys
SELECT
table_name,
column_name,
referenced_table_name,
referenced_column_name
FROM information_schema.KEY_COLUMN_USAGE
WHERE table_schema = DATABASE()
AND referenced_table_schema IS NOT NULL;
-- Find unique constraints
SELECT
constraint_name,
table_name,
column_name
FROM information_schema.TABLE_CONSTRAINTS c
JOIN information_schema.KEY_COLUMN_USAGE k
ON c.constraint_name = k.constraint_name
WHERE c.table_schema = DATABASE()
AND c.constraint_type = 'UNIQUE';#Metadata Functions
#Database Information Functions
-- Current database
SELECT DATABASE();
SELECT SCHEMA();
-- Current user
SELECT USER();
SELECT CURRENT_USER();
SELECT SESSION_USER();
-- Connection ID
SELECT CONNECTION_ID();
-- Last insert ID
SELECT LAST_INSERT_ID();
#Table Information Functions
-- Row count
SELECT ROW_COUNT();
-- Auto increment value
SELECT @@auto_increment_increment;
-- Check table existence
SELECT COUNT(*)
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
AND table_name = 'users';#Practical Examples
#Database Documentation
-- Generate table documentation
SELECT
t.table_name,
t.table_comment,
t.engine,
c.column_name,
c.data_type,
c.is_nullable,
c.column_default,
c.column_comment
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 = DATABASE()
ORDER BY t.table_name, c.ordinal_position;#Schema Comparison
-- Compare tables between databases
SELECT
COALESCE(a.table_name, b.table_name) AS table_name,
CASE
WHEN a.table_name IS NULL THEN 'Only in B'
WHEN b.table_name IS NULL THEN 'Only in A'
ELSE 'In both'
END AS status
FROM (
SELECT table_name FROM information_schema.TABLES
WHERE table_schema = 'database_a'
) a
FULL OUTER JOIN (
SELECT table_name FROM information_schema.TABLES
WHERE table_schema = 'database_b'
) b ON a.table_name = b.table_name;#Unused Indexes
-- Find potentially unused indexes
SELECT
t.table_name,
s.index_name,
s.column_name,
s.cardinality,
t.table_rows
FROM information_schema.STATISTICS s
JOIN information_schema.TABLES t
ON s.table_name = t.table_name
WHERE s.table_schema = DATABASE()
AND s.index_name != 'PRIMARY'
AND s.cardinality IS NULL;#Foreign Key Report
-- Generate foreign key documentation
SELECT
kcu.table_name AS child_table,
kcu.column_name AS child_column,
kcu.referenced_table_name AS parent_table,
kcu.referenced_column_name AS parent_column,
rc.update_rule,
rc.delete_rule
FROM information_schema.KEY_COLUMN_USAGE kcu
JOIN information_schema.REFERENTIAL_CONSTRAINTS rc
ON kcu.constraint_name = rc.constraint_name
WHERE kcu.table_schema = DATABASE()
ORDER BY kcu.table_name, kcu.constraint_name;#Summary
MySQL metadata provides:
- Database Information: Names, sizes, engines
- Table Information: Columns, rows, indexes
- Column Information: Types, defaults, constraints
- Index Information: Keys, cardinality, uniqueness
- Performance Data: Queries, waits, I
- **User
Use metadata for database administration, documentation, optimization, and monitoring.
Previous: Clone Tables
Next: Sequences