3 esquemas PostgreSQL para um aplicativo limpo — estruturando o Supabase desde o início
Quando você inicia um projeto, a tentação é grande de colocar tudo no esquema public do PostgreSQL. Uma tabela aqui, outra ali, e em três semanas você se encontra com 40 tabelas misturadas sem nenhuma lógica.
Decidi muito cedo estruturar o TAMSIV com três esquemas separados.
Os três esquemas
privat— Todos os dados pessoais: tarefas, memorandos, eventos de calendário, perfis de usuário, anexoscollaborative— Tudo relacionado a grupos: membros, funções, tarefas compartilhadas, listas de verificação de grupogamification— Estatísticas, distintivos, sequências, desafios diários, histórico de pontos
Por que privat e não private? Porque private é uma palavra reservada em SQL. Aprendi isso da pior forma depois de uma migração falha.
Por que separar?
1. Legibilidade. Quando faço SELECT * FROM privat.tasks, sei imediatamente que é um dado pessoal.
2. Segurança. As políticas RLS são mais fáceis de raciocinar quando as tabelas são agrupadas por domínio. As regras do esquema privat são simples: você só vê seus dados. As do esquema collaborative são mais complexas: você vê os dados dos grupos dos quais é membro, de acordo com sua função.
3. Evolução. Quando adicionei a gamificação três meses após o início do projeto, criei um novo esquema sem tocar nos outros dois. Risco zero de quebrar o existente.
O pesadelo das políticas RLS
O Supabase usa RLS para proteger o acesso aos dados. O princípio é simples: cada tabela tem regras que determinam quem pode ler, escrever, modificar, excluir. Na prática, é um labirinto.
No total, o projeto tem mais de 30 políticas RLS. Cada uma testada individualmente.
As convenções de nomenclatura
Adotei convenções rigorosas: tabelas em snake_case no plural, colunas em snake_case, parâmetros RPC com prefixo p_. Este prefixo p_ evita colisões com nomes de colunas nas consultas. No dia em que seu parâmetro user_id entra em conflito com a coluna user_id, você entende o porquê.
Essa estrutura me economizou um tempo considerável no futuro. Cada nova funcionalidade encontra seu lugar naturalmente.