Estação 4 · 08:45
Fundamentação técnica
Dez argumentos, sustentados pelo PostgreSQL, pelo TypeScript e pelas maiores empresas de tecnologia do mundo. Leia com calma e um café do lado.
🦆
Duck typing no banco
Ninguém declara o que é cliente e o que é pedido. O pedido é pedido porque tem preço. Um trem é definido pelo que ele carrega.
SELECT pedido.*
FROM trem AS cliente
JOIN trem AS pedido
ON pedido.trem_id = cliente.id
WHERE cliente.email = 'ze@uai.com.br'
AND pedido.preco_em_centavos IS NOT NULL;
🏢
A indústria chegou lá pela metade
- Bigtable, HBase e Cassandra são tabelas esparsas com colunas quase sempre vazias.
- A AWS recomenda single-table design no DynamoDB.
- O Rails tem Single Table Inheritance há quase vinte anos.
- O Protobuf 3 removeu os campos
required.
- No GraphQL, campo aceita nulo por padrão.
Cada um achou um pedaço. Minas achou a verdade inteira, e com café.
🙏
Toda coluna opcional é honestidade
No mundo real, todo dado pode faltar. O endereço veio sem número porque "é a casa amarela depois da venda do Seu Tião". Um NOT NULL é uma promessa que o mundo não vai cumprir.
Trem não é any. O any desiste de tipar. O Trem sabe o que pode ter, só não exige que tenha.
🔄
Migrations nunca mais quebram nada
No PostgreSQL, adicionar coluna nula sem default só mexe em metadados. É instantâneo. Cliente antigo ignora a coluna nova, cliente novo usa. Compatibilidade pra frente e pra trás, de fábrica.
ALTER TABLE trem ADD COLUMN cor text;
-- pronto. ninguém quebrou.
🫥
Nulo sai de graça
No PostgreSQL, um valor nulo gasta um bit no null bitmap da linha. O vazio no trem é quase de graça, igual ao silêncio mineiro. Pra performance, cada "entidade" ganha seu índice parcial.
CREATE INDEX trem_pedidos ON trem (trem_id)
WHERE preco_em_centavos IS NOT NULL;
🕸️
Muitos-para-muitos é trem
Um trem que liga um trem a outro trem é um trem.
INSERT INTO trem (origem_id, destino_id)
VALUES ('aluno', 'disciplina');
De quebra, a tabela vira também um banco de grafos.
🧠
Metade da Ciência da Computação resolvida
"Só existem duas coisas difíceis em Ciência da Computação: invalidação de cache e dar nome às coisas." (Phil Karlton)
Ninguém mais discute User contra Usuario, nem singular contra plural. É trem. A invalidação de cache fica pra depois.
⏱️
Onboarding em um segundo
Dev novo pergunta: "Qual é o modelo de dados?"
Resposta: "Trem."
Onboarding concluído. Pode pegar a primeira task.
🧪
Testes sem fixture
O menor trem válido é o objeto vazio. Ele compila e entra no banco. Todo teste começa dele e acrescenta só o que precisa.
const tremPrimordial: Trem = {};
INSERT INTO trem DEFAULT VALUES;
🧩
TypeScript é estrutural, e o trem também
No TypeScript, o que define um tipo é a forma, e não o nome. No trem, o que define um pedido é ter preço. Banco e linguagem pensam igual. O ORM fica com um model só e a impedância objeto-relacional some.