<< All versions
Skill v1.0.0
currentAutomated scan100/100bug-ops/zeph/database
──Details
PublishedOctober 30, 2026 at 03:30 AM
Content Hashsha256:e5c147a312ec68f3...
Git SHAc68c5deee4d6
──Files
Files (1 file, 12.1 KB)
SKILL.md12.1 KBactive
SKILL.md · 461 lines · 12.1 KB
name: database category: data description: > Query and manage SQLite, PostgreSQL, and MySQL databases from the command line. Use when the user asks to run SQL queries, inspect database schemas, create or alter tables, import or export data, manage indexes, analyze query performance with EXPLAIN, back up or restore databases, or perform CRUD operations via sqlite3, psql, or mysql CLI tools. license: MIT compatibility: Requires sqlite3, psql, or mysql CLI tools depending on the database engine metadata: author: zeph version: "1.0"
Database CLI Operations
Quick Reference
| Action | SQLite | PostgreSQL | MySQL | |
|---|---|---|---|---|
| Connect | sqlite3 db.sqlite | psql -U user -d dbname | mysql -u user -p dbname | |
| List databases | .databases | \l | SHOW DATABASES; | |
| List tables | .tables | \dt | SHOW TABLES; | |
| Describe table | .schema tablename | \d tablename | DESCRIBE tablename; | |
| Quit | .quit | \q | \q or exit | |
| Run file | .read file.sql | \i file.sql | source file.sql |
SQLite (sqlite3)
Connection and Configuration
bash
# Open or create a databasesqlite3 mydb.sqlite# Open read-onlysqlite3 -readonly mydb.sqlite# Execute SQL directly (non-interactive)sqlite3 mydb.sqlite "SELECT * FROM users;"# Execute SQL from filesqlite3 mydb.sqlite < queries.sqlsqlite3 mydb.sqlite ".read queries.sql"# Output modessqlite3 mydb.sqlite -header -column "SELECT * FROM users;"sqlite3 mydb.sqlite -json "SELECT * FROM users;"sqlite3 mydb.sqlite -csv "SELECT * FROM users;"sqlite3 mydb.sqlite -markdown "SELECT * FROM users;"
Dot Commands
bash
.help # List all dot commands.tables # List all tables.tables %user% # List tables matching pattern.schema # Show CREATE statements for all tables.schema users # Show CREATE statement for specific table.indexes # List all indexes.indexes users # List indexes for specific table.headers on # Show column headers.mode column # Columnar output (also: csv, json, markdown, table, line).width 20 10 30 # Set column widths.timer on # Show query execution time.dbinfo # Show database metadata.dump # Dump entire database as SQL.dump users # Dump specific table.import file.csv users # Import CSV into table.output result.txt # Redirect output to file.output stdout # Reset output to terminal.changes on # Show number of rows changed.eqp on # Show query plan automatically
Schema Operations
sql
-- Create tableCREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,email TEXT UNIQUE,created_at TEXT DEFAULT (datetime('now')));-- Add columnALTER TABLE users ADD COLUMN role TEXT DEFAULT 'user';-- Rename tableALTER TABLE users RENAME TO app_users;-- Create indexCREATE INDEX idx_users_email ON users(email);CREATE UNIQUE INDEX idx_users_name ON users(name);-- Drop indexDROP INDEX idx_users_email;-- Analyze (update query planner statistics)ANALYZE;
CRUD Operations
sql
-- InsertINSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com'), ('Carol', 'carol@example.com');-- SelectSELECT * FROM users WHERE role = 'admin' ORDER BY name LIMIT 10;SELECT name, COUNT(*) as cnt FROM orders GROUP BY name HAVING cnt > 5;-- UpdateUPDATE users SET role = 'admin' WHERE email = 'alice@example.com';-- DeleteDELETE FROM users WHERE created_at < datetime('now', '-1 year');-- Upsert (insert or replace)INSERT OR REPLACE INTO users (id, name, email) VALUES (1, 'Alice', 'alice@new.com');INSERT INTO users (name, email) VALUES ('Alice', 'alice@new.com')ON CONFLICT(email) DO UPDATE SET name = excluded.name;
Import and Export
bash
# Export to CSVsqlite3 -header -csv mydb.sqlite "SELECT * FROM users;" > users.csv# Export to JSONsqlite3 -json mydb.sqlite "SELECT * FROM users;" > users.json# Import CSVsqlite3 mydb.sqlite <<'EOF'.mode csv.import users.csv usersEOF# Backup (SQL dump)sqlite3 mydb.sqlite .dump > backup.sql# Restore from dumpsqlite3 newdb.sqlite < backup.sql# Binary backup (online, safe while database is in use)sqlite3 mydb.sqlite ".backup backup.sqlite"
Query Analysis
sql
-- Query planEXPLAIN QUERY PLAN SELECT * FROM users WHERE email = 'alice@example.com';-- Full explainEXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';-- Integrity checkPRAGMA integrity_check;-- Database size infoPRAGMA page_count;PRAGMA page_size;-- Table infoPRAGMA table_info(users);-- Foreign key checkPRAGMA foreign_key_check;-- WAL mode (recommended for concurrent access)PRAGMA journal_mode=WAL;-- Optimize after bulk operationsVACUUM;
PostgreSQL (psql)
Connection
bash
# Connect to local databasepsql -U postgres -d mydb# Connect with host and portpsql -h localhost -p 5432 -U myuser -d mydb# Connection string (URI)psql "postgresql://user:password@host:5432/dbname?sslmode=require"# Execute SQL directlypsql -U postgres -d mydb -c "SELECT * FROM users;"# Execute SQL filepsql -U postgres -d mydb -f queries.sql# Output formattingpsql -U postgres -d mydb --csv -c "SELECT * FROM users;"psql -U postgres -d mydb -t -A -c "SELECT count(*) FROM users;" # tuples only, unaligned
Meta-Commands
\l -- List all databases\c dbname -- Connect to database\dt -- List tables in current schema\dt public.* -- List tables in public schema\dt+ users -- Table details with size\d users -- Describe table (columns, types, constraints)\d+ users -- Extended description (storage, stats)\di -- List indexes\di+ idx_users_email -- Index details\dn -- List schemas\df -- List functions\dv -- List views\du -- List roles/users\dp users -- Show table privileges\x -- Toggle expanded display (vertical rows)\timing -- Toggle query timing display\i file.sql -- Execute SQL file\o output.txt -- Send output to file\o -- Reset output to terminal\! command -- Execute shell command\e -- Edit query in $EDITOR\g -- Execute last query again\s -- Show command history\pset format csv -- Set output format (csv, html, latex, wrapped)
Schema Inspection
sql
-- List all tables with sizesSELECT schemaname, tablename,pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename))FROM pg_tablesWHERE schemaname = 'public'ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC;-- List columns for a tableSELECT column_name, data_type, is_nullable, column_defaultFROM information_schema.columnsWHERE table_name = 'users'ORDER BY ordinal_position;-- List indexesSELECT indexname, indexdefFROM pg_indexesWHERE tablename = 'users';-- List foreign keysSELECT conname, conrelid::regclass, confrelid::regclassFROM pg_constraintWHERE contype = 'f' AND conrelid = 'users'::regclass;-- Active connectionsSELECT pid, usename, datname, state, queryFROM pg_stat_activityWHERE state = 'active';
Backup and Restore
bash
# Dump single database (SQL)pg_dump -U postgres mydb > backup.sql# Dump with compressionpg_dump -U postgres -Fc mydb > backup.dump# Dump schema onlypg_dump -U postgres --schema-only mydb > schema.sql# Dump data onlypg_dump -U postgres --data-only mydb > data.sql# Dump single tablepg_dump -U postgres -t users mydb > users.sql# Dump all databasespg_dumpall -U postgres > all_databases.sql# Restore from SQL dumppsql -U postgres mydb < backup.sql# Restore from custom formatpg_restore -U postgres -d mydb backup.dump# Restore single tablepg_restore -U postgres -d mydb -t users backup.dump
Query Analysis
sql
-- Execution planEXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';-- Execution plan with actual runtime statsEXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)SELECT * FROM users WHERE email = 'alice@example.com';-- Table statisticsSELECT relname, n_live_tup, n_dead_tup, last_vacuum, last_autovacuumFROM pg_stat_user_tables;-- Index usage statisticsSELECT indexrelname, idx_scan, idx_tup_read, idx_tup_fetchFROM pg_stat_user_indexesWHERE schemaname = 'public';-- Update statisticsANALYZE users;ANALYZE; -- all tables-- Slow queries (requires pg_stat_statements extension)SELECT query, calls, mean_exec_time, total_exec_timeFROM pg_stat_statementsORDER BY mean_exec_time DESCLIMIT 10;
MySQL (mysql)
Connection
bash
# Connectmysql -u root -pmysql -u myuser -p mydbmysql -h hostname -P 3306 -u myuser -p mydb# Execute SQL directlymysql -u root -p -e "SELECT * FROM users;" mydb# Execute SQL filemysql -u root -p mydb < queries.sql# Output formattingmysql -u root -p -N -B -e "SELECT count(*) FROM users;" mydb # raw value
Meta-Commands
sql
SHOW DATABASES;USE mydb;SHOW TABLES;SHOW TABLE STATUS;DESCRIBE users; -- column detailsSHOW CREATE TABLE users; -- full CREATE statementSHOW INDEX FROM users;SHOW PROCESSLIST; -- active connectionsSHOW VARIABLES LIKE '%max%'; -- server variablesSHOW STATUS LIKE 'Threads%'; -- server status
Backup and Restore
bash
# Dump single databasemysqldump -u root -p mydb > backup.sql# Dump with compressionmysqldump -u root -p mydb | gzip > backup.sql.gz# Dump schema onlymysqldump -u root -p --no-data mydb > schema.sql# Dump specific tablesmysqldump -u root -p mydb users orders > tables.sql# Dump all databasesmysqldump -u root -p --all-databases > all.sql# Restoremysql -u root -p mydb < backup.sql# Restore compressedgunzip < backup.sql.gz | mysql -u root -p mydb
Query Analysis
sql
-- Execution planEXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';-- Extended explain (JSON format, MySQL 5.7+)EXPLAIN FORMAT=JSON SELECT * FROM users WHERE email = 'alice@example.com';-- Analyze (update index statistics)ANALYZE TABLE users;-- Check table integrityCHECK TABLE users;-- Optimize table (reclaim space)OPTIMIZE TABLE users;-- Show index cardinalitySHOW INDEX FROM users;
Common SQL Patterns
sql
-- PaginationSELECT * FROM items ORDER BY id LIMIT 20 OFFSET 40;-- Count with groupingSELECT status, COUNT(*) as cnt FROM orders GROUP BY status ORDER BY cnt DESC;-- JoinSELECT u.name, o.totalFROM users uJOIN orders o ON u.id = o.user_idWHERE o.created_at > '2024-01-01';-- SubquerySELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > 100);-- CTE (Common Table Expression)WITH active_users AS (SELECT * FROM users WHERE last_login > '2024-01-01')SELECT * FROM active_users WHERE role = 'admin';-- Window functionsSELECT name, department, salary,RANK() OVER (PARTITION BY department ORDER BY salary DESC) as rankFROM employees;-- Conditional aggregationSELECTCOUNT(*) as total,SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active,SUM(CASE WHEN status = 'inactive' THEN 1 ELSE 0 END) as inactiveFROM users;
Important Notes
- Always back up before destructive operations (DROP, DELETE, TRUNCATE, ALTER)
- Use transactions for multi-statement changes:
BEGIN; ... COMMIT;(orROLLBACK;) - Prefer
EXPLAIN ANALYZEoverEXPLAINto see actual vs estimated row counts - For SQLite, use WAL mode (
PRAGMA journal_mode=WAL) for concurrent read/write - For PostgreSQL, use
\xfor wide tables to get vertical output - For MySQL, add
\Gat the end of a query for vertical output - Use
-t(tuples only) and-A(unaligned) in psql for scriptable output - Never store passwords in command-line arguments; use
.pgpass(psql) or.my.cnf(mysql) - Use parameterized queries in scripts to prevent SQL injection