Padronização de escrita SQL

Bom dia pessoal!!!

Padronização de escrita do SQL é importante para o desenvolvimento de sistemas. Contudo não concordo com a forma que alguns colegas escrevem as suas consultas e gostaria de opinião de vocês.

1 - Sou contra o uso de alias em uma consulta;

Por exemplo:

SELECT cliente.nome,
       endereco.rua,
       endereco.numero,
       endereco.cidade,
       tipo_telefone.descricao,
       telefone.numero,
       pedido.valor_total,
       tipo_pedido.descricao,
       produto.descricao,
       produto.valor,
       item_pedido.quantidade
       item_pedido.valor_total
FROM cliente 
    INNER JOIN endereco
      ON (cliente.id = endereco.id_cliente)
    LEFT JOIN telefone
      ON (cliente.id = telefone.id_cliente)
    INNER JOIN tipo_telefone
      ON (telefone.id_tipo_telefone = tipo_telefone.id)
    INNER JOIN pedido
      ON (cliente.id = pedido.id_cliente)
    INNER JOIN tipo_pedido
      ON (pedido.id_tipo_pedido = tipo_pedido.id)
    INNER JOIN item_pedido
      ON (pedido.id = item_pedido.id_pedido)
    INNER JOIN produto
      ON (item_pedido.id_produto = produto.id)
WHERE cliente.ativo = true
  AND pedido.valor_total > 1000
ORDER BY cliente.nome

Dessa forma eu consigo enxergar sem problemas a qual tabela pertence cada campo. Vejamos o mesmo sql, utilizando alias:

SELECT c.nome,
       e.rua,
       e.numero,
       e.cidade,
       tt.descricao,
       t.numero,
       p.valor_total,
       tp.descricao,
       pr.descricao,
       pr.valor,
       ip.quantidade
       ip.valor_total
FROM cliente c 
    INNER JOIN endereco e
      ON (c.id = e.id_cliente)
    LEFT JOIN telefone t
      ON (c.id = t.id_cliente)
    INNER JOIN tipo_telefone tt
      ON (t.id_tipo_telefone = tt.id)
    INNER JOIN pedido p
      ON (c.id = p.id_cliente)
    INNER JOIN tipo_pedido tp
      ON (p.id_tipo_pedido = tp.id)
    INNER JOIN item_pedido ip
      ON (p.id = ip.id_pedido)
    INNER JOIN produto pr
      ON (ip.id_produto = pr.id)
WHERE c.ativo = true
  AND p.valor_total > 1000
ORDER BY c.nome

OK. O sql ficou menor! Porém, dessa forma eu tenho dificuldades em identificar a qual tabela pertence cada campo. Assim sendo, tenho que consultar na estrutura do FROM o que significa determinada sigla!

2 - Sou a favor da indentação do código para facilitar a leitura (inclusive no código fonte do sistema).

Vejamos o mesmo código sem indentação:

SELECT cliente.nome,
endereco.rua,
endereco.numero,
endereco.cidade,
tipo_telefone.descricao,
telefone.numero,
pedido.valor_total,
tipo_pedido.descricao,
produto.descricao,
produto.valor,
item_pedido.quantidade
item_pedido.valor_total
FROM cliente 
INNER JOIN endereco ON (cliente.id = endereco.id_cliente)
LEFT JOIN telefone ON (cliente.id = telefone.id_cliente)
INNER JOIN tipo_telefone ON (telefone.id_tipo_telefone = tipo_telefone.id)
INNER JOIN pedido ON (cliente.id = pedido.id_cliente)
INNER JOIN tipo_pedido ON (pedido.id_tipo_pedido = tipo_pedido.id)
INNER JOIN item_pedido ON (pedido.id = item_pedido.id_pedido)
INNER JOIN produto ON (item_pedido.id_produto = produto.id)
WHERE cliente.ativo = true
AND pedido.valor_total > 1000
ORDER BY cliente.nome

Percebem como fica mais difícil para realizar a leitura? Já peguei consultas muito maiores do que essa. Por isso, acho fundamental criar uma padronização.

Por favor deem suas opiniões!

Legal seu ponto de vista!
Eu trabalho com a estruturas sql dando apelidos para as tabelas para facilitar a digitação e diminuir o tamanho do código, mesmo que seja pouco já ajuda, porém eu tomo o devido cuidado com os apelidos, devido que hoje sou eu quem crio e dou manutenção, porém amanhã poderá ser outra pessoa.
Lógico que isso vai da consciência de boa prática de cada um, por que vamos pensar da seguinte maneira um pequeno exemplo com 2 tabelas.

GE_CADCIDADE -- GE antes do nome da tabela significa que a mesma é de Gerais logo após CAD para indicar que é uma tabela de cadastro, logo cidade pertence a cadastros gerais.
ES_MOVPRODUTO -- ES antes do nome da tabela significa que a mesma é de Estoque logo após MOV para indicar que é uma tabela de movimentação, logo produto pertence a movimentação de estoque.

Da mesma maneira assim como mostrei nos 2 exemplos acima, pode-se utilizar FI para todas tabelas de financeiro, RH para todas as tabelas de recursos humanos e assim sucessivamente, não é uma regra, mas um facilitador, imaginando um BD com + de 200 tabelas facilmente você localiza as mesmas pelas siglas iniciais.

Como eu trabalho apelidando as tabelas

GE_CADCIDADE -> CADCID --Perceba que mesmo apelidando eu consigo identificar facilmente
ES_MOVPRODUTO -> MOVPRO

Já a prática aplicada por boa parte seria da seguinte maneira

GE_CADCIDADE -> X --Aqui sim faz todo o sentido no que você disse
ES_MOVPRODUTO -> Y
1 curtida

Eu sou extremamente a favor de identar o script SQL.
Quanto a dar apelidos as tabelas, esses devem ser criados de forma cuidadosa, para não ficar igual ao exemplo que você listou, mas há casos que é interessante apelidar as tabelas, por exemplo:

Sem apelidos

Select 
         Id,
         Nome,
         Sku
From OdtCurrentOrderInPoint
    JOIN OdtCurrentOrderInPointItens 
            on OdtCurrentOrderInPointItens.Id = OdtCurrentOrderInPoint.Id
            and OdtCurrentOrderInPointItens.IdCliente = OdtCurrentOrderInPoint.IdCliente
WHERE
     OdtCurrentOrderInPointItens.Id = 10           

Com apelidos

Select 
         Cabecalho.Id,
         Cabecalho.Nome,
         Itens.Sku
From OdtCurrentOrderInPoint Cabecalho
    JOIN OdtCurrentOrderInPointItens  Itens
            on Itens.Id = Cabecalho.Id
            and Itens.IdCliente = Cabecalho.IdCliente
WHERE
     Cabecalho.Id = 10
1 curtida

Bacana. Eu já trabalhei em uma empresa que fazia algo parecido.

m_pedido_venda - M de tabela mestre;
d_itens_pedido_venda - D de tabela detalhe;
b_status - B de tabela básica…

E assim por diante. Além disso eles colocavam o tipo primitido no nome do campo:

i_cod_m_pedido_venda - I de inteiro;
s_descricao_m_pedido_venda - S de String ou Varchar;
dt_m_pedido_venda - DT de date;

1 curtida

Enquanto eu nao vejo problemas com as duas práticas que citou (evitar alias, indentar script), confesso que nao considero nenhuma delas tao importante assim.

O uso de alias pra mim nao é problema, pois prefiro manter minhas queries curtas. Se consigo ler a query inteira de uma vez, é muito simples ver ao que o alias se refere. Se você tem queries de 20, 50 linhas, entao você já tem desafios maiores pra manter isso de qualquer jeito.

Indentaçao também nao conta tanto, pois pode ser facilmente automatizada. Se fosse fazer um review do seu código eu provavelmente ficaria mais interessado no fato do select envolver 8 tabelas, ou a necessidade de uma tabela de tipos para telefones… e ainda aquele LEFT JOIN antes dos INNER JOINS (com a mesma tabela sendo usada num INNER JOIN depois, que sempre me deixa confuso*).

  • Para clarificar, usar INNER JOIN em tipo_telefone daquele jeito efetivamente “transforma” o LEFT JOIN anterior num INNER JOIN
1 curtida

Eu entendo sua motivaçao aqui, mas nao seria melhor ao invés de emular um separaçao em módulos utilizando prefixos, usar um sistema de módulos verdadeiro fornecido pelo banco? Por exemplo, separar a tabelas de financeiro e RH em seus respectivos esquemas? Ou até diferente bancos de dados?
Mesmo sem usar micro-serviços, quebrar as coisas em tamanhos menores ajuda todo mundo a entender o sistema em uma maneira geral.

1 curtida

Não teria que pagar mais pelas licenças de banco de dados adicionais?

No caso isso seria um padrão de projeto, motivação seria outra coisa que nem cabe neste contexto, ou não entendi bem o que você quis dizer aqui!

Na verdade o que você disse pode muito bem ser utilizado, isso quando se tem um projeto que exige a modulação dentro do BD, o que geralmente não vejo muito, conheço diversos softwares comerciais de médio a grande porte onde se tem o BD como um todo, ou seja sem modulação, onde tabelas são separadas por padrões de nomenclatura indicando tipos e diversos tipos de informações de acordo com o que a empresa/equipe define para o projeto, e a modulação é toda trabalhada de forma externa.
Mas lógico, ambas podem ser utilizadas, afinal, nada impede ou atrapalha no funcionamento do software, entendo tudo isso como apenas padrões de projetos.