333 lines
7.8 KiB
Markdown
333 lines
7.8 KiB
Markdown
|
|
# 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 | ❌ | ✅ |
|
||
|
|
|
||
|
|
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.
|