Effective PostgreSQL: Item 6 – Design Foreign Keys with Appropriate ON DELETE/UPDATE Actions

The Problem: Default Behavior Causes Unexpected Issues You’re building a blog platform with users and posts. The naive approach uses a simple foreign key: What happens when you try to delete a user? The default behavior is ON DELETE RESTRICT – prevents deletion if child rows exist. Problem Scenarios with Default Behavior Scenario 1: Can’t … Read more

Effective PostgreSQL: Item 5 – Use ENUM Types for Fixed Sets of Values

The Problem: String Columns Without Constraints You’re building an order management system. Orders have statuses like “pending”, “processing”, “shipped”, and “delivered”. The naive approach uses a TEXT column: What could go wrong? Problem 1: Typos Create Invalid Data Problem 2: No Discoverability New developers (or AI assistants!) don’t know what valid statuses are: Problem 3: … Read more

Effective PostgreSQL: Item 4 – Prefer DOMAIN Types for Reusable Validation

The Problem: Repeating Validation Logic Everywhere You’re building a system with email addresses scattered across multiple tables: Problems with this approach: Problem 1: Copy-Paste Error Prone One typo in the regex and you have inconsistent validation: Problem 2: Difficult to Update Validation Rules Business decides to allow longer TLDs (.museum, .international): Problem 3: No Self-Documentation … Read more

Effective PostgreSQL: Item 3 – Use EXCLUSION Constraints for Temporal Data

The Problem: Overlapping Reservations Are Hard to Prevent You’re building a conference room booking system. Each reservation has a start and end time. The business rule is simple: no two reservations can overlap for the same room. Here’s the naive approach using a UNIQUE constraint: Why this fails: The UNIQUE (room_id, start_time) only prevents exact … Read more

Effective PostgreSQL: Item 2 – Use citext for Case-Insensitive Identifiers

The Problem: Case Sensitivity Creates User Experience Nightmares You’ve built a user registration system. Alice signs up with [email protected]. A week later, she tries to log in but types [email protected]. Your login fails because PostgreSQL’s TEXT type is case-sensitive: This is frustrating for users and creates duplicate account problems: The Naive Solution: LOWER() Everywhere The … Read more

Effective PostgreSQL: Item 1: Favor CHECK constraints over application-level validation

The Problem: Application-Level Validation is Fragile Picture this: You’re building an e-commerce platform. Your product pricing logic is carefully implemented in your API layer: Looks solid, right? But here’s what can go wrong: Scenario 1: The Midnight Migration Your DevOps engineer runs a data migration script at 2 AM to fix some corrupted records: Scenario … Read more