Dicas para melhorar seu SQL
Essas melhores práticas vão desde a pequenas dicas de como realizar algo específico até a padrões de nomenclatura. Várias delas são aplicáveis a qualquer SGBD e outras são exclusivas do PostgreSQL.
Neste artigo vou compartilhar 5 dessas melhores práticas.
#1 — Padrão definido de nomenclatura
Para tabelas, definimos que a primeira palavra do nome da tabela se refere a funcionalidade (ou escopo) e as demais servem para especificar a função da tabela em si:
Exemplo: produto, produto_estoque, produto_preco
De começo pode parecer desnecessário, mas quando o sistema crescer para centenas de tabelas, vai ser extremamente útil ter todas as tabelas de um mesmo escopo agrupadas.
No caso das functions, nós fazemos todas as nossas começarem com “func”, seguidas pelo nome da funcionalidade (ou escopo) e depois o nome da func em si:
Nós também definimos que os parâmetros passados para as functions devem começar com “f” e que as variáveis definidas internamente devem começar com “v”. Por exemplo: f_id_usuario para um parâmetro que a function recebe e v_id_usuario para uma variável declarada internamente pela function. Essa é uma distinção que não é necessária a nível de aplicação mas que ajuda bastante a nível de banco.
Aqui um exemplo irreal apenas para ilustrar o padrão de nomenclatura para as functions:
create or replace function func_usuario_insere(f_nome text, f_endereco text) returns void language plpgsqlas$$declare v_data_hora_atual constant timestamp with time zone = now();begin -- SQL aqui.end;$$;
#2 — SQL minúsculo
O case ideal para escrever SQL é um tema polêmico. Por aqui não foi diferente. Começamos com a regra de escrever todo SQL em maiúsculo. Ficamos um bom tempo escrevendo assim, para nós fazia sentido. Porém, com o passar do tempo, um ou outro membro do time começou a perceber SQL minúsculo era mais amigável para escrever e ler. Chegamos a um ponto onde alguns escreviam em minúsculo e mudavam para maiúsculo antes de abrir PR para deixar no padrão do time. Vou dizer apenas uma coisa: é um caminho sem volta. Depois que é experimentado, não tem como voltar a desenvolver em maiúsculo. Hoje percebemos, inclusive, que a leitura de nossos códigos em minúsculo fluem muito melhor.
#3 — Alias em todas as queries
Além de deixar suas queries mais otimizadas, você vai estar se protegendo de um possível problema do qual já sofremos aqui.
Imagine a seguinte query:
select *from usuario join cargo on usuario.id_cargo = cargo.idwhere status_ativo = true;
Recomendados pelo LinkedIn
A coluna status_ativo, pela qual o filtro foi feito. Existe apenas na tabela usuario. Porém, agora imagine que a coluna status_ativo foi também adicionada na tabela cargo. Isso vai quebrar o SQL acima, pois o banco não tem mais como saber na coluna de qual tabela você quer aplicar o filtro “= true”.
Uma versão muito melhor (apesar de pouco diferente) da query acima é essa:
select *from usuario us join cargo cg on us.id_cargo = cg.idwhere us.status_ativo = true;
Obs.: Utilize alias que fazem sentido em querys longas.
#4 — Não utilizar “select *”
Provavelmente você já ouviu falar que isso não é uma boa prática, mas não custa relembrar. Não utilize “select *”, sempre opte por especificar quais colunas você quer que retorne de uma busca. Além de deixar mais claro quais informações serão utilizadas, sua query fica mais otimizada, pois não retorna nada além do necessário. Em alguns casos, um “select *” pode até mesmo inviabilizar a aplicação de um index.
Por exemplo, se você quer buscar nome e endereço de um usuário. Ao invés disso:
select u.* from usuario u where u.id = 1;
Faça o seguinte:
select u.nome, u.endereco from usuario u where u.id = 1;
#5 — Colunas not null sempre que possível
Se você pode fazer uma coluna ser not null, então faça! Valores nulos no banco, assim como a nível de aplicação, não são autoexplicativos: é a inexistência de valor ou um valor inválido? Além do que, alguns SGBDs não lidam muito bem com nulls, então evite eles.
Se no seu design algo precisa ser nulo, tente repensá-lo para algum jeito onde a nulidade possa ser evitada.
Perceba, é claro, que isso não é uma verdade absoluta. Nós temos várias colunas que podem ser null, mas foram escolhas pensadas e não o acaso. Também é bom considerar que, se para evitar um valor nulo em uma coluna é preciso expandir demais o design, talvez seja melhor lidar com nulls mesmo. Por aqui acreditamos que overengineering é pior do que a nulidade.
Seguimos a máxima do clean code: “Wheter you are designing systems or individual modules, never forget to use the simplest thing that can possibly work”.
Dica adicional: E uma ultima dica, não tente resolver tudo em uma query, pode ficar lento, confuso e de manutenção difícil. O melhor é fazer uma boa modelagem e um bom planejamento de código. Utilize sempre o plano de execução para avaliar os resultados da consulta, pois qualquer banco de dados pode Crescer a centendas de megabytes.
Carlos Henrique Diehl 2023