ERD Best Practices from the Field
A good ERD makes development easier; a bad ERD can derail an entire project. Here are 10 battle-tested ERD design best practices.
1. Apply Naming Conventions Consistently
Agree on naming conventions for table and column names before starting the project.
Recommendations:
- Table names: use either singular or plural consistently (e.g., always
useror alwaysusers) - Column names: choose either snake_case or camelCase and stick to it
- Primary keys: standardize as
idortable_name_id - Foreign keys: include the referenced table name (
user_id,product_id) - Date columns: use consistent suffixes like
created_at,updated_at,deleted_at
Inconsistent naming causes confusion when writing SQL and bugs in auto-generated queries.
2. Define a Primary Key for Every Table
Tables without primary keys create major data manipulation difficulties. Choose either UUID or auto-increment integers based on your project needs.
- UUID: Good for distributed systems and externally-exposed IDs (
550e8400-e29b-41d4-a716-446655440000) - Integer Sequence: Better for simple internal systems where performance is critical
3. Always Include created_at and updated_at
Include creation timestamp (created_at) and modification timestamp (updated_at) in nearly every table. Without these columns, debugging and data analysis become frustratingly difficult.
Add deleted_at for soft delete functionality when needed.
4. Resolve Many-to-Many Relationships with Junction Tables
N:M relationships must always be managed through a junction table (also called a bridge table or associative table).
Wrong approach: Adding a course_ids array column to the student table
Correct approach: Create a student_courses junction table:
student_id(FK → students)course_id(FK → courses)- Composite primary key: (student_id, course_id)
- Additional attributes possible:
enrolled_at,grade, etc.
5. Explicitly Define Foreign Key Constraints
Foreign key constraints guarantee data integrity at the database level. Relying only on application-level validation is risky.
Clearly specify delete behavior:
ON DELETE CASCADE: Delete children when parent is deleted (comments with posts)ON DELETE RESTRICT: Prevent parent deletion when children exist (safe default)ON DELETE SET NULL: Set FK to NULL when parent is deleted (posts without authors)
6. Plan Indexes Proactively
Planning indexes at design time is more efficient than adding them after performance issues arise.
When indexes are needed:
- Foreign key columns (explicitly add even if DB creates them automatically)
- Columns frequently used in WHERE clauses (
status,user_id,created_at) - Columns frequently used in JOINs
- Columns frequently used in ORDER BY
7. Choose Appropriate Data Types
Data types directly affect storage space and query performance.
- Email:
VARCHAR(255) - Long text:
TEXT - Monetary amounts:
DECIMAL(10, 2)(avoids floating-point errors) - Datetime:
TIMESTAMP WITH TIME ZONE(timezone-aware) - Boolean:
BOOLEANorTINYINT(1) - Country codes:
CHAR(2)(ISO 3166) - Status values:
ENUMorVARCHARwith check constraints
8. Be Deliberate About NULL Allowance
Carefully decide whether each column allows NULL. Unnecessary NULL allowance complicates queries, and missing NULL checks cause bugs.
- Columns that must always have a value:
NOT NULL - Optional information: Allow NULL
- Columns with sensible defaults:
NOT NULL DEFAULT 'value'
9. Avoid Circular References
Circular references — where A references B and B references A — cause insertion and deletion problems. If truly necessary, handle with nullable FK columns, but preferably redesign to eliminate them.
10. Maintain ERDs as Living Documents
An ERD isn't drawn once and forgotten. Update it as the system evolves. Include ERD files in version control (Git) alongside code and track change history.
With Erdmates, your entire team can collaboratively edit ERDs in real-time, immediately reflecting changes. Generate SQL DDL from ERDs automatically or import existing SQL to keep documentation synchronized with actual code.
Conclusion
Good ERD design doesn't happen overnight. It improves iteratively through repeated design cycles and team reviews. Use these 10 principles as a checklist whenever starting a new project.