Table Design Best Practices
Good table design prevents future pain.
A few disciplined choices now can save many migrations, bug fixes, and data cleanup scripts later.
Core Concepts
flowchart LR
A[Identify entities] --> B[Pick clear keys]
B --> C[Add required constraints]
C --> D[Set sane defaults]
D --> E[Review with real query needs]
| Design area | Recommended default | Why |
|---|---|---|
| Primary key | INTEGER PRIMARY KEY | Simple, efficient identity |
| Required fields | NOT NULL | Prevent missing critical values |
| Business uniqueness | UNIQUE (+ NOT NULL when required) | Prevent duplicates |
| Validation | CHECK | Keep bad values out |
| Audit creation time | DEFAULT CURRENT_TIMESTAMP | Consistent row metadata |
- Do This
- Avoid This
- Use descriptive names (
customer_id,created_at) - Keep one fact per column
- Prefer small, explicit constraints
- Use integer ids for most internal keys
- Generic column names (
data,misc) - Comma-separated lists in one column
- Schema with no primary key
- Relying only on app validation
Code Examples
-- Example of a well-structured table for common app data.
CREATE TABLE customers (
customer_id INTEGER PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
full_name TEXT NOT NULL,
age INTEGER CHECK (age >= 0),
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
| Expected output |
|---|
Table customers created with key constraints and defaults. |
-- Verify the final schema text.
SELECT sql
FROM sqlite_schema
WHERE type = 'table' AND name = 'customers';
| sql |
|---|
CREATE TABLE customers (... email TEXT NOT NULL UNIQUE ... CHECK (age >= 0) ...) |
SQLite-Specific Nuances
SQLite Nuance
Because SQLite is flexible with typing, schema constraints are even more important for preserving data quality.
Think of constraints as your first line of defense.
Common Pitfalls / Best Practices
Pitfall
Creating tables quickly without constraints and planning to "clean data later".
Data cleanup almost always costs more than prevention.
Best Practice
Before finalizing a table, run this checklist: primary key, required fields, uniqueness, validation, defaults.
Quick Challenge
Design a books table with:
book_idprimary key- required
title - required + unique
isbn pricemust be non-negativecreated_atdefault timestamp
View Solution
CREATE TABLE books (
book_id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
isbn TEXT NOT NULL UNIQUE,
price REAL CHECK (price >= 0),
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
| Expected output |
|---|
| Table created with identity, quality constraints, and creation timestamp. |