<< All versions

Skill v1.0.0

currentAutomated scan100/100
bug-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

ActionSQLitePostgreSQLMySQL
Connectsqlite3 db.sqlitepsql -U user -d dbnamemysql -u user -p dbname
List databases.databases\lSHOW DATABASES;
List tables.tables\dtSHOW TABLES;
Describe table.schema tablename\d tablenameDESCRIBE tablename;
Quit.quit\q\q or exit
Run file.read file.sql\i file.sqlsource file.sql

SQLite (sqlite3)

Connection and Configuration

bash
# Open or create a database
sqlite3 mydb.sqlite
# Open read-only
sqlite3 -readonly mydb.sqlite
# Execute SQL directly (non-interactive)
sqlite3 mydb.sqlite "SELECT * FROM users;"
# Execute SQL from file
sqlite3 mydb.sqlite < queries.sql
sqlite3 mydb.sqlite ".read queries.sql"
# Output modes
sqlite3 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 table
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
created_at TEXT DEFAULT (datetime('now'))
);
-- Add column
ALTER TABLE users ADD COLUMN role TEXT DEFAULT 'user';
-- Rename table
ALTER TABLE users RENAME TO app_users;
-- Create index
CREATE INDEX idx_users_email ON users(email);
CREATE UNIQUE INDEX idx_users_name ON users(name);
-- Drop index
DROP INDEX idx_users_email;
-- Analyze (update query planner statistics)
ANALYZE;

CRUD Operations

sql
-- Insert
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com'), ('Carol', 'carol@example.com');
-- Select
SELECT * FROM users WHERE role = 'admin' ORDER BY name LIMIT 10;
SELECT name, COUNT(*) as cnt FROM orders GROUP BY name HAVING cnt > 5;
-- Update
UPDATE users SET role = 'admin' WHERE email = 'alice@example.com';
-- Delete
DELETE 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 CSV
sqlite3 -header -csv mydb.sqlite "SELECT * FROM users;" > users.csv
# Export to JSON
sqlite3 -json mydb.sqlite "SELECT * FROM users;" > users.json
# Import CSV
sqlite3 mydb.sqlite <<'EOF'
.mode csv
.import users.csv users
EOF
# Backup (SQL dump)
sqlite3 mydb.sqlite .dump > backup.sql
# Restore from dump
sqlite3 newdb.sqlite < backup.sql
# Binary backup (online, safe while database is in use)
sqlite3 mydb.sqlite ".backup backup.sqlite"

Query Analysis

sql
-- Query plan
EXPLAIN QUERY PLAN SELECT * FROM users WHERE email = 'alice@example.com';
-- Full explain
EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';
-- Integrity check
PRAGMA integrity_check;
-- Database size info
PRAGMA page_count;
PRAGMA page_size;
-- Table info
PRAGMA table_info(users);
-- Foreign key check
PRAGMA foreign_key_check;
-- WAL mode (recommended for concurrent access)
PRAGMA journal_mode=WAL;
-- Optimize after bulk operations
VACUUM;

PostgreSQL (psql)

Connection

bash
# Connect to local database
psql -U postgres -d mydb
# Connect with host and port
psql -h localhost -p 5432 -U myuser -d mydb
# Connection string (URI)
psql "postgresql://user:password@host:5432/dbname?sslmode=require"
# Execute SQL directly
psql -U postgres -d mydb -c "SELECT * FROM users;"
# Execute SQL file
psql -U postgres -d mydb -f queries.sql
# Output formatting
psql -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 sizes
SELECT schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename))
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC;
-- List columns for a table
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'users'
ORDER BY ordinal_position;
-- List indexes
SELECT indexname, indexdef
FROM pg_indexes
WHERE tablename = 'users';
-- List foreign keys
SELECT conname, conrelid::regclass, confrelid::regclass
FROM pg_constraint
WHERE contype = 'f' AND conrelid = 'users'::regclass;
-- Active connections
SELECT pid, usename, datname, state, query
FROM pg_stat_activity
WHERE state = 'active';

Backup and Restore

bash
# Dump single database (SQL)
pg_dump -U postgres mydb > backup.sql
# Dump with compression
pg_dump -U postgres -Fc mydb > backup.dump
# Dump schema only
pg_dump -U postgres --schema-only mydb > schema.sql
# Dump data only
pg_dump -U postgres --data-only mydb > data.sql
# Dump single table
pg_dump -U postgres -t users mydb > users.sql
# Dump all databases
pg_dumpall -U postgres > all_databases.sql
# Restore from SQL dump
psql -U postgres mydb < backup.sql
# Restore from custom format
pg_restore -U postgres -d mydb backup.dump
# Restore single table
pg_restore -U postgres -d mydb -t users backup.dump

Query Analysis

sql
-- Execution plan
EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';
-- Execution plan with actual runtime stats
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM users WHERE email = 'alice@example.com';
-- Table statistics
SELECT relname, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum
FROM pg_stat_user_tables;
-- Index usage statistics
SELECT indexrelname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
WHERE schemaname = 'public';
-- Update statistics
ANALYZE users;
ANALYZE; -- all tables
-- Slow queries (requires pg_stat_statements extension)
SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;

MySQL (mysql)

Connection

bash
# Connect
mysql -u root -p
mysql -u myuser -p mydb
mysql -h hostname -P 3306 -u myuser -p mydb
# Execute SQL directly
mysql -u root -p -e "SELECT * FROM users;" mydb
# Execute SQL file
mysql -u root -p mydb < queries.sql
# Output formatting
mysql -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 details
SHOW CREATE TABLE users; -- full CREATE statement
SHOW INDEX FROM users;
SHOW PROCESSLIST; -- active connections
SHOW VARIABLES LIKE '%max%'; -- server variables
SHOW STATUS LIKE 'Threads%'; -- server status

Backup and Restore

bash
# Dump single database
mysqldump -u root -p mydb > backup.sql
# Dump with compression
mysqldump -u root -p mydb | gzip > backup.sql.gz
# Dump schema only
mysqldump -u root -p --no-data mydb > schema.sql
# Dump specific tables
mysqldump -u root -p mydb users orders > tables.sql
# Dump all databases
mysqldump -u root -p --all-databases > all.sql
# Restore
mysql -u root -p mydb < backup.sql
# Restore compressed
gunzip < backup.sql.gz | mysql -u root -p mydb

Query Analysis

sql
-- Execution plan
EXPLAIN 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 integrity
CHECK TABLE users;
-- Optimize table (reclaim space)
OPTIMIZE TABLE users;
-- Show index cardinality
SHOW INDEX FROM users;

Common SQL Patterns

sql
-- Pagination
SELECT * FROM items ORDER BY id LIMIT 20 OFFSET 40;
-- Count with grouping
SELECT status, COUNT(*) as cnt FROM orders GROUP BY status ORDER BY cnt DESC;
-- Join
SELECT u.name, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.created_at > '2024-01-01';
-- Subquery
SELECT * 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 functions
SELECT name, department, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as rank
FROM employees;
-- Conditional aggregation
SELECT
COUNT(*) 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 inactive
FROM users;

Important Notes

  • Always back up before destructive operations (DROP, DELETE, TRUNCATE, ALTER)
  • Use transactions for multi-statement changes: BEGIN; ... COMMIT; (or ROLLBACK;)
  • Prefer EXPLAIN ANALYZE over EXPLAIN to see actual vs estimated row counts
  • For SQLite, use WAL mode (PRAGMA journal_mode=WAL) for concurrent read/write
  • For PostgreSQL, use \x for wide tables to get vertical output
  • For MySQL, add \G at 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
All versions