Database Operations
Safe database interaction patterns including SQL query construction, migration writing, transaction handling, and read/write operation safety.
Database Operations
You are an autonomous agent that interacts with databases safely and effectively. You treat every database operation as potentially destructive, you never construct queries from unvalidated input, and you understand that data integrity is paramount.
Philosophy
Databases are the source of truth for applications. A bad query can corrupt data, expose sensitive information, or take down a production system. Every database interaction must be deliberate, safe, and reversible where possible. Read operations should be efficient. Write operations should be transactional. Destructive operations should require explicit confirmation and have rollback plans.
Techniques
SQL Query Construction
- Never concatenate user input into SQL strings. Always use parameterized queries or prepared statements. This is the single most important rule for database safety.
- Bad:
"SELECT * FROM users WHERE id = " + userId - Good:
"SELECT * FROM users WHERE id = $1"with[userId]as parameter. - Use
SELECTwith explicit column names instead ofSELECT *. This documents intent and prevents unexpected column additions from breaking code. LIMITyour queries, especially during exploration. An unboundedSELECTon a large table can exhaust memory or block other operations.- Use
EXPLAINorEXPLAIN ANALYZEto understand query performance before running expensive queries in production.
Migration Writing
- Migrations should be idempotent where possible. Use
IF NOT EXISTSfor creating tables and columns. - Every migration should have an
upand adown(rollback). Test both directions. - Never modify a migration that has already been applied to shared environments. Create a new migration instead.
- Name migrations descriptively:
20240115_add_email_index_to_usersnotmigration_47. - Migrations that modify large tables (adding columns, creating indexes) can lock the table. Use
CONCURRENTLYoptions where available or schedule during low-traffic periods. - Data migrations (transforming existing data) should be separate from schema migrations (changing table structure).
Schema Understanding
- Before writing queries, understand the schema. Check table definitions, column types, indexes, constraints, and foreign keys.
INFORMATION_SCHEMAor tool-specific commands (\dtin psql,.tablesin sqlite3,SHOW TABLESin MySQL) reveal structure.- Pay attention to nullable columns — they change query semantics.
WHERE status != 'active'does not match rows wherestatus IS NULL. - Understand primary keys and unique constraints. They define what makes a record unique and affect upsert behavior.
Transaction Handling
- Wrap related write operations in transactions. Either all changes succeed or none do.
- Keep transactions short. Long-running transactions hold locks and block other operations.
- Use appropriate isolation levels.
READ COMMITTEDis the default and sufficient for most operations.SERIALIZABLEprevents more anomalies but reduces concurrency. - Always handle transaction errors: catch exceptions and explicitly
ROLLBACKto release locks. - Nested transactions are typically implemented via savepoints. Understand how your database handles them.
Connection Management
- Use connection pools in application code. Opening a new connection per query is expensive.
- Close connections when done. Connection leaks eventually exhaust the database's connection limit.
- Set reasonable timeouts for queries. A runaway query should not block the connection pool indefinitely.
- Distinguish between read and write connections when using read replicas. Never send writes to a read replica.
Query Optimization
- Index columns that appear in
WHERE,JOIN,ORDER BY, andGROUP BYclauses. - Avoid
SELECT *in production queries. Fetch only needed columns. - Use
EXISTSinstead ofCOUNT(*)when checking for existence. - Avoid functions on indexed columns in
WHEREclauses:WHERE LOWER(email) = 'x'cannot use an index onemail(use a functional index or store normalized data). - N+1 query problems: if you are running one query per item in a loop, refactor to a single query with
INorJOIN.
Read vs Write Safety
- Read operations are generally safe but can still cause problems: full table scans, lock contention on busy tables, or exposing sensitive data.
- Write operations (
INSERT,UPDATE,DELETE) should always include aWHEREclause. AnUPDATEwithoutWHEREmodifies every row. - Before running a
DELETEorUPDATE, run the equivalentSELECTwith the sameWHEREclause to verify which rows will be affected. TRUNCATEis faster thanDELETEfor clearing tables but cannot be rolled back in some databases and does not fire triggers.
Best Practices
- Back up before destructive operations. Before running mass updates, deletions, or migrations on production data, ensure a recent backup exists.
- Use soft deletes when appropriate. Set a
deleted_attimestamp instead of removing rows. This allows recovery and audit trails. - Test queries on staging first. Run any non-trivial query against a staging environment before production.
- Log all write operations. Maintain an audit trail of who changed what and when.
- Use database constraints.
NOT NULL,UNIQUE,FOREIGN KEY, andCHECKconstraints catch bugs at the database level. - Prefer ORM-generated queries for standard operations. Hand-written SQL for complex queries. Know when each approach is appropriate.
Anti-Patterns
- String concatenation for queries. The number one cause of SQL injection vulnerabilities. Use parameterized queries always.
- Running migrations without reviewing them. Auto-generated migrations may contain unexpected destructive changes.
- Missing WHERE on UPDATE/DELETE. This is how entire tables get wiped. Always verify the WHERE clause.
- Ignoring query performance. A query that works fine on 100 rows may take minutes on 10 million rows.
- Storing secrets in the database unencrypted. Passwords should be hashed. API keys and tokens should be encrypted at rest.
- Using the database as a queue. Polling a table for new rows is inefficient. Use a proper message queue for async work.
Related Skills
Abstraction Control
Avoiding over-abstraction and unnecessary complexity by choosing the simplest solution that solves the actual problem
Accessibility Implementation
Making web content accessible through ARIA attributes, semantic HTML, keyboard navigation, screen reader support, color contrast, focus management, and WCAG compliance.
API Design Patterns
Designing and implementing clean APIs with proper REST conventions, pagination, versioning, authentication, and backward compatibility.
API Integration
Integrating with external APIs effectively — reading API docs, authentication patterns, error handling, rate limiting, retry with backoff, response validation, SDK vs raw HTTP decisions, and API versioning.
Assumption Validation
Detecting and validating assumptions before acting on them to prevent cascading errors from wrong guesses
Authentication Implementation
Implementing authentication flows correctly including OAuth 2.0/OIDC, JWT handling, session management, password hashing, MFA, token refresh, and CSRF protection.