Rustelo/docs/database-configuration.md

333 lines
7.8 KiB
Markdown
Raw Normal View History

# Database Configuration Guide
This application supports both **PostgreSQL** and **SQLite** databases through SQLx's unified interface. The database type is automatically detected based on the connection URL.
## Quick Start
### SQLite (Recommended for Development)
```toml
[database]
url = "sqlite:database.db"
```
### PostgreSQL (Recommended for Production)
```toml
[database]
url = "postgresql://username:password@localhost:5432/database_name"
```
## Database URL Formats
### SQLite URLs
- `sqlite:database.db` - Relative path to database file
- `sqlite:///path/to/database.db` - Absolute path to database file
- `sqlite::memory:` - In-memory database (testing only)
### PostgreSQL URLs
- `postgresql://user:password@host:port/database`
- `postgres://user:password@host:port/database`
## Environment Variables
You can override the database URL using environment variables:
```bash
export DATABASE_URL="sqlite:my_database.db"
# or
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
```
## Database-Specific Features
### SQLite
- **Pros:**
- Zero configuration setup
- Single file database
- Perfect for development and testing
- No separate server process required
- ACID compliant
- **Cons:**
- Limited concurrent writes
- No network access
- Fewer advanced features
- File-based storage
### PostgreSQL
- **Pros:**
- Full ACID compliance
- Excellent concurrent access
- Advanced features (JSONB, arrays, etc.)
- Network accessible
- Production-ready scalability
- **Cons:**
- Requires PostgreSQL server
- More complex setup
- Resource overhead
## Configuration Examples
### Development Configuration
```toml
# config.dev.toml
[database]
url = "sqlite:dev_database.db"
max_connections = 5
min_connections = 1
connect_timeout = 30
idle_timeout = 300
max_lifetime = 1800
```
### Production Configuration
```toml
# config.prod.toml
[database]
url = "postgresql://prod_user:${DATABASE_PASSWORD}@db.example.com:5432/prod_database"
max_connections = 20
min_connections = 5
connect_timeout = 30
idle_timeout = 600
max_lifetime = 3600
```
## Connection Pool Settings
| Setting | Description | SQLite | PostgreSQL |
|---------|-------------|--------|------------|
| `max_connections` | Maximum pool size | 1 (recommended) | 10-50 |
| `min_connections` | Minimum pool size | 1 | 1-5 |
| `connect_timeout` | Connection timeout (seconds) | 30 | 30 |
| `idle_timeout` | Idle connection timeout (seconds) | 300 | 600 |
| `max_lifetime` | Maximum connection lifetime (seconds) | 1800 | 3600 |
## Database Setup
### SQLite Setup
No setup required! The database file will be created automatically when the application starts.
### PostgreSQL Setup
#### Using Docker
```bash
# Start PostgreSQL container
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=password \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
postgres:15
# Connect to database
docker exec -it postgres psql -U postgres -d myapp
```
#### Using Local Installation
**macOS (Homebrew):**
```bash
brew install postgresql
brew services start postgresql
createdb myapp
```
**Ubuntu/Debian:**
```bash
sudo apt-get install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo -u postgres createdb myapp
```
## Migration Support
The application automatically creates the necessary tables for both database types:
### SQLite Tables
- Uses `TEXT` for IDs (UUID format)
- Uses `DATETIME` for timestamps
- Uses `TEXT` for JSON storage
- Uses `BOOLEAN` for boolean values
### PostgreSQL Tables
- Uses `UUID` for IDs with `gen_random_uuid()`
- Uses `TIMESTAMPTZ` for timestamps
- Uses `JSONB` for JSON storage
- Uses `BOOLEAN` for boolean values
## Switching Between Databases
You can switch between databases by simply changing the `DATABASE_URL`:
```bash
# Switch to SQLite
export DATABASE_URL="sqlite:database.db"
# Switch to PostgreSQL
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
```
The application will automatically:
1. Detect the database type
2. Use appropriate SQL syntax
3. Create compatible table schemas
4. Handle data type differences
## Performance Considerations
### SQLite
- **Best for:**
- Single-user applications
- Development and testing
- Small to medium datasets
- Read-heavy workloads
- **Optimization tips:**
- Use WAL mode: `PRAGMA journal_mode=WAL`
- Set appropriate timeout: `PRAGMA busy_timeout=5000`
- Use transactions for bulk operations
### PostgreSQL
- **Best for:**
- Multi-user applications
- Production environments
- Large datasets
- High concurrency requirements
- **Optimization tips:**
- Configure appropriate connection pool size
- Use indexes on frequently queried columns
- Monitor and tune PostgreSQL configuration
- Use connection pooling (PgBouncer) for high traffic
## Troubleshooting
### Common SQLite Issues
- **Database locked**: Check for long-running transactions
- **File permissions**: Ensure write access to database file and directory
- **Disk space**: Verify sufficient disk space for database growth
### Common PostgreSQL Issues
- **Connection refused**: Check PostgreSQL server status
- **Authentication failed**: Verify username/password and pg_hba.conf
- **Too many connections**: Adjust max_connections or use connection pooling
### Debug Connection Issues
```bash
# Test SQLite connection
sqlite3 database.db "SELECT 1;"
# Test PostgreSQL connection
psql "postgresql://user:pass@localhost:5432/mydb" -c "SELECT 1;"
```
## Environment-Specific Configuration
### Development
```bash
# .env.development
DATABASE_URL=sqlite:dev_database.db
```
### Testing
```bash
# .env.test
DATABASE_URL=sqlite::memory:
```
### Production
```bash
# .env.production
DATABASE_URL=postgresql://user:${DATABASE_PASSWORD}@db.internal:5432/prod_db
```
## Security Considerations
### SQLite Security
- Protect database file permissions (600 or 640)
- Backup database files securely
- Consider encryption for sensitive data
### PostgreSQL Security
- Use strong passwords
- Enable SSL/TLS connections
- Restrict network access
- Regular security updates
- Use connection pooling with authentication
## Backup and Recovery
### SQLite Backup
```bash
# Simple file copy
cp database.db database_backup.db
# Using SQLite backup command
sqlite3 database.db ".backup database_backup.db"
```
### PostgreSQL Backup
```bash
# Database dump
pg_dump myapp > myapp_backup.sql
# Restore from dump
psql myapp < myapp_backup.sql
```
## Monitoring and Maintenance
### SQLite Maintenance
```sql
-- Analyze database
ANALYZE;
-- Vacuum database
VACUUM;
-- Check integrity
PRAGMA integrity_check;
```
### PostgreSQL Maintenance
```sql
-- Analyze tables
ANALYZE;
-- Vacuum tables
VACUUM;
-- Check database size
SELECT pg_size_pretty(pg_database_size('myapp'));
```
## Best Practices
1. **Use environment variables** for database URLs in production
2. **Configure appropriate connection pools** based on your workload
3. **Monitor database performance** and adjust settings as needed
4. **Regular backups** are essential for production databases
5. **Test migrations** on both database types if supporting both
6. **Use transactions** for data consistency
7. **Index frequently queried columns** for better performance
8. **Monitor connection pool usage** to prevent exhaustion
## Feature Compatibility Matrix
| Feature | SQLite | PostgreSQL |
|---------|--------|------------|
| ACID Transactions | ✅ | ✅ |
| Concurrent Reads | ✅ | ✅ |
| Concurrent Writes | ⚠️ Limited | ✅ |
| JSON Support | ✅ (TEXT) | ✅ (JSONB) |
| Full-text Search | ✅ (FTS) | ✅ (Built-in) |
| Network Access | ❌ | ✅ |
| Replication | ❌ | ✅ |
| Partitioning | ❌ | ✅ |
| Custom Functions | ✅ | ✅ |
| Triggers | ✅ | ✅ |
| Views | ✅ | ✅ |
| Stored Procedures | ❌ | ✅ |
2026-02-08 20:37:49 +00:00
This guide should help you choose and configure the right database for your needs. Both options are fully supported and the application will work seamlessly with either choice.