Noções Básicas de Design de Esquema
9 exemplos para você começar com o design de esquema - 6 básicos e 3 intermediários.
Pré-requisitos
CREATE em um banco de dados de desenvolvimento.
# Desenvolvimento local com Docker (PostgreSQL 18)
docker run -d --name pg18 -e POSTGRES_PASSWORD=dev -p 5432:5432 postgres:18
psql postgres://postgres:dev@localhost:5432/postgresExemplos Básicos
1. Chave Primária Substituta
ID opaco gerado pelo banco de dados.
CREATE TABLE app.accounts (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name text NOT NULL
);- Estável quando as chaves naturais do negócio mudam
- Referências FK estreitas
- Expor o ID nas APIs de forma consistente
2. Chave Única Natural
Identificador de negócio com constraint UNIQUE.
CREATE TABLE app.accounts (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
external_ref text NOT NULL UNIQUE,
name text NOT NULL
);- UNIQUE garante a identidade de sistemas upstream
- Manter PK substituta para junções
- Documentar a origem de external_ref
3. Nomenclatura de Tabelas
Substantivos plurais e prefixo de esquema.
CREATE TABLE app.order_lines (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
order_id bigint NOT NULL,
sku text NOT NULL,
qty int NOT NULL CHECK (qty > 0)
);- Plural ou singular consistente por padrão da organização
- Prefixe colunas com o contexto da tabela ao fazer junções amplas
- Evitar palavras reservadas
4. Coluna de Chave Estrangeira
Nomeie a coluna filha como parent_table_id.
ALTER TABLE app.order_lines
ADD CONSTRAINT order_lines_order_id_fkey
FOREIGN KEY (order_id) REFERENCES app.orders(id);- Comportamento explícito de ON DELETE é necessário no design
- Indexar colunas FK em tabelas filhas
- NOT NULL quando o relacionamento é obrigatório
5. Padrões NOT NULL
Reduzir a ambiguidade de NULL.
CREATE TABLE app.settings (
account_id bigint PRIMARY KEY REFERENCES app.accounts(id),
theme text NOT NULL DEFAULT 'light'
);- Padrões aceleram as inserções
- NOT NULL quando o desconhecido é inválido
- NULL reservado para desconhecidos opcionais
6. Constraints CHECK
Regras de linha aplicadas pelo banco de dados.
ALTER TABLE app.order_lines
ADD CONSTRAINT order_lines_qty_positive CHECK (qty > 0);- Sobrevivem a bugs de aplicativos
- Constraints nomeadas melhoram as mensagens de erro
- Documentar em comentários de migração
Exemplos Intermediários
7. Chave Natural Composta
Quando o par de negócio é único.
CREATE TABLE app.region_codes (
country char(2) NOT NULL,
region_code text NOT NULL,
name text NOT NULL,
PRIMARY KEY (country, region_code)
);- Bom para dados de referência puros
- FKs mais amplas em tabelas filhas
- Considerar substituta se a largura da FK for importante
8. Coluna de Exclusão Lógica
deleted_at marca linhas inativas.
ALTER TABLE app.accounts ADD COLUMN deleted_at timestamptz;
CREATE INDEX accounts_active_idx ON app.accounts (id) WHERE deleted_at IS NULL;- Índice parcial mantém o conjunto ativo pequeno
- Constraints de unicidade podem precisar de índice único parcial
- Vacuum ainda processa tuplas mortas
9. Comentários em Objetos
Documentação do catálogo.
COMMENT ON TABLE app.accounts IS 'Tenant billing account';
COMMENT ON COLUMN app.accounts.external_ref IS 'CRM id';- Visível em
psql \d+e catálogos de dados - Sobrevive à regeneração do ORM se as migrações controlarem o DDL
- Ajuda no onboarding
Versões da Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x e PostGIS 3.5+.