PRIMARY KEY: INT/BIGINT com IDENTITY ou SERIAL
Inegociável desde sempre.
O campo de chave primária é o eixo de rotação de toda tabela. Use INT (até ~2 bilhões de linhas) ou BIGINT (além disso). Sempre com geração automática — IDENTITY no SQL Server, SERIAL/GENERATED ALWAYS AS IDENTITY no PostgreSQL.
Nunca exponha esse ID em APIs públicas ou URLs. Ele é interno, sequencial e previsível — o que é ótimo para performance de B-Tree, péssimo para segurança.
-- PostgreSQL
CREATE TABLE orders (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
public_id UUID NOT NULL DEFAULT gen_random_uuid(),
-- ...
CONSTRAINT uq_orders_public_id UNIQUE (public_id)
);
-- SQL Server
CREATE TABLE orders (
id BIGINT IDENTITY(1,1) PRIMARY KEY,
public_id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID(),
-- ...
CONSTRAINT uq_orders_public_id UNIQUE (public_id)
);O índice UNIQUE na coluna public_id garante integridade sem custo de fragmentação no clustered index. É o melhor dos dois mundos: performance interna, segurança externa.