Translate

Mostrar mensagens com a etiqueta COBOL PadawanBella. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta COBOL PadawanBella. Mostrar todas as mensagens

sexta-feira, 18 de maio de 2018

SQL JOINs: O Que Todo Programador COBOL Padawan Precisa Saber Para Entender Como os Bancos de Dados Pensam

 

Bellacosa Mainframe e o uso dos sqljoins em SQL

☕ Um Café no Bellacosa Mainframe

SQL JOINs: O Que Todo Programador COBOL Padawan Precisa Saber Para Entender Como os Bancos de Dados Pensam

Você não está apenas aprendendo comandos SQL. Está aprendendo como bilhões de registros conversam entre si todos os dias.

Existem momentos na carreira de um programador em que um conceito muda completamente sua forma de enxergar a computação.

Para alguns, esse momento acontece ao aprender ponteiros em C.

Para outros, ao descobrir orientação a objetos.

Para quem trabalha com bancos de dados relacionais, esse momento geralmente acontece quando entende, de verdade, os JOINs.

À primeira vista, parecem apenas quatro comandos:

  • INNER JOIN

  • LEFT JOIN

  • RIGHT JOIN

  • FULL OUTER JOIN

Mas, por trás deles, existe uma das maiores invenções da Ciência da Computação moderna.

Para um programador COBOL, compreender JOINs é semelhante a descobrir que, em vez de navegar manualmente por dezenas de arquivos VSAM procurando registros relacionados, existe um mecanismo matemático capaz de fazer isso automaticamente, de forma otimizada, segura e extremamente rápida.

Pegue seu café.

Hoje vamos conversar sobre como os bancos de dados realmente pensam.


Antes do SQL

Imagine que estamos em 1975.

Você trabalha em um grande banco.

Os dados estão espalhados em arquivos.

Existe um arquivo de clientes.

Outro de contas.

Outro de cartões.

Outro de empréstimos.

Outro de movimentações.

Em COBOL, o processamento normalmente seria algo parecido com:

Ler Cliente

Para cada Cliente

    Abrir arquivo de Contas

    Procurar Conta

        Abrir arquivo de Movimentos

        Procurar Movimentos

            Gerar relatório

Nada de errado.

Foi assim durante décadas.

Mas existe um problema.

À medida que os arquivos crescem...

...o processamento cresce junto.

Às vezes de forma exponencial.

Era necessário pensar diferente.


Surge o Modelo Relacional

Em 1970, Edgar F. Codd publicou um artigo que mudou a história da informática.

Sua ideia era brilhante.

Em vez de navegar manualmente entre arquivos...

...o programador apenas declararia:

"Quero relacionar estas duas tabelas."

O banco descobriria o melhor caminho.

Foi o nascimento do SQL moderno.

E junto dele...

...os JOINs.


O que é um JOIN?

JOIN significa literalmente

Junção.

É a operação que une informações de duas ou mais tabelas utilizando algum relacionamento.

Imagine duas tabelas.

CLIENTE

IDNome
1João
2Maria
3Carlos
4Ana

PEDIDO

PedidoClienteValor
1011250
1021400
1033120
1045900

Observe.

O pedido possui um campo chamado CLIENTE.

Esse campo aponta para o ID da tabela CLIENTE.

Visualmente:

CLIENTE

1 João
2 Maria
3 Carlos
4 Ana

        │

        ▼

PEDIDO

101 Cliente 1

102 Cliente 1

103 Cliente 3

104 Cliente 5

Existe um relacionamento.

É justamente isso que o JOIN explora.


INNER JOIN

É o JOIN mais famoso.

Ele responde uma pergunta muito simples.

"Quais registros existem nos dois lados?"

SQL

SELECT
    C.NOME,
    P.VALOR
FROM CLIENTE C
INNER JOIN PEDIDO P
ON C.ID = P.CLIENTE_ID;

Resultado

ClienteValor
João250
João400
Carlos120

Perceba.

Maria desapareceu.

Ana desapareceu.

O pedido do cliente 5 também desapareceu.

Por quê?

Porque não existe correspondência.

O INNER JOIN trabalha exclusivamente com a interseção.

Imagine dois círculos.

CLIENTES

(1 2 3 4)

PEDIDOS

(1 3 5)

Resultado

(1 3)

Apenas aquilo que existe em ambos.


A mágica acontece automaticamente

Quando você escreve:

INNER JOIN

Você não está dizendo ao banco:

"Leia primeiro esta tabela."

Nem:

"Depois percorra aquela."

Nem:

"Faça um loop."

Você apenas declara o resultado desejado.

O banco escolhe como chegar nele.

Esse é o paradigma declarativo.


LEFT JOIN

Agora imagine outra pergunta.

"Quero todos os clientes."

Mesmo aqueles que nunca compraram.

É aqui que entra o LEFT JOIN.

SELECT
    C.NOME,
    P.VALOR
FROM CLIENTE C
LEFT JOIN PEDIDO P
ON C.ID=P.CLIENTE_ID;

Resultado

ClienteValor
João250
João400
MariaNULL
Carlos120
AnaNULL

Observe o NULL.

Ele não significa zero.

Não significa vazio.

Significa simplesmente:

"Não existe registro correspondente."

Esse pequeno detalhe causa milhares de erros em sistemas corporativos.


Descobrindo clientes inativos

Um dos usos mais comuns do LEFT JOIN.

SELECT C.*

FROM CLIENTE C

LEFT JOIN PEDIDO P

ON C.ID=P.CLIENTE_ID

WHERE P.CLIENTE_ID IS NULL;

Resultado.

Maria.

Ana.

São clientes cadastrados.

Mas nunca fizeram pedidos.

Esse tipo de consulta é extremamente comum em:

  • CRM

  • Bancos

  • Seguradoras

  • Telecom

  • E-commerce


RIGHT JOIN

É simplesmente o espelho do LEFT.

Mantém todos os registros da direita.

Na prática...

Poucos desenvolvedores utilizam RIGHT JOIN.

A maioria prefere inverter as tabelas e continuar usando LEFT JOIN.

É mais intuitivo.


FULL OUTER JOIN

Esse é o mais democrático.

Nada é descartado.

Tudo aparece.

Clientes com pedidos.

Clientes sem pedidos.

Pedidos sem clientes.

Tudo.

CLIENTES

1

2

3

4

PEDIDOS

1

3

5

Resultado

1

2

3

4

5

Muito utilizado em auditorias.

Migração de sistemas.

Comparação de bases.

Validação de integrações.


O papel do NULL

Uma das maiores dificuldades dos iniciantes.

Imagine.

Maria nunca comprou.

O resultado será

Maria

NULL

Não escreva

WHERE VALOR=0

Porque NULL não é zero.

Use

WHERE VALOR IS NULL

Parece detalhe.

Mas não é.


O problema da multiplicação de registros

Esse é um conceito que surpreende muitos programadores COBOL.

Imagine.

Um cliente.

Cinco pedidos.

CLIENTE

João
PEDIDO

101

102

103

104

105

Resultado do JOIN.

João

101

João

102

João

103

João

104

João

105

Um registro virou cinco.

Isso é perfeitamente normal.

É consequência da cardinalidade.


Cardinalidade

Existem quatro situações clássicas.

Um para Um

Pessoa

CPF

Cada pessoa possui apenas um CPF.


Um para Muitos

Cliente

Pedidos

Um cliente possui vários pedidos.

É o relacionamento mais comum.


Muitos para Um

Milhares de pedidos.

Um cliente.

É apenas a visão inversa.


Muitos para Muitos

Aluno

Disciplina

Um aluno cursa várias disciplinas.

Uma disciplina possui vários alunos.

Nesse caso normalmente existe uma terceira tabela intermediária.


O erro que derruba servidores

Todo DBA conhece essa história.

Um desenvolvedor escreve:

SELECT *

FROM CLIENTE,

PEDIDO;

Ou

JOIN

sem ON

Resultado.

Produto Cartesiano.

Se houver:

100.000 clientes

100.000 pedidos

O banco produzirá

10 bilhões de combinações.

Pode consumir CPU, memória e I/O de forma devastadora.

Por isso, nunca execute um JOIN sem uma condição de relacionamento bem definida.


Como o DB2 realmente executa um JOIN?

Aqui entramos no mundo do IBM Mainframe.

Você escreve SQL.

Mas quem decide o caminho é o Otimizador do DB2.

Ele analisa dezenas de fatores.

Quantidade de registros.

Índices.

Estatísticas.

Cardinalidade.

Distribuição dos valores.

Buffer Pool.

Espaço disponível.

Custo estimado.

No final...

Escolhe um plano de execução.

É semelhante ao GPS.

Você informa o destino.

Ele calcula a melhor rota.


Nested Loop Join

Imagine duas listas telefônicas.

Você pega um nome.

Procura na outra lista.

Repete.

Esse é o Nested Loop.

Cliente

↓

Índice

↓

Pedido

Excelente quando existe índice.

Muito utilizado em consultas seletivas.


Merge Join

Agora imagine duas listas ordenadas alfabeticamente.

Você percorre ambas ao mesmo tempo.

Sem voltar.

Sem pesquisar novamente.

Muito eficiente para grandes conjuntos já classificados.


Hash Join

Agora imagine uma tabela hash.

Os registros menores são colocados em memória.

Depois a outra tabela apenas consulta essa estrutura.

É extremamente rápido para determinadas situações.


O papel dos índices

Sem índices...

O banco precisa procurar registro por registro.

Com índices...

Ele encontra rapidamente os dados desejados.

Imagine um livro de 2.000 páginas.

Sem índice.

Você folheia página por página.

Com índice.

Vai diretamente ao assunto.

É exatamente isso que acontece.


RUNSTATS

No DB2 existe um utilitário extremamente importante.

RUNSTATS.

Ele atualiza as estatísticas do banco.

Quantidade de linhas.

Número de páginas.

Distribuição dos valores.

Percentual de registros.

Sem essas informações...

O otimizador pode escolher um caminho ruim.

É como dirigir sem GPS.


EXPLAIN

Todo desenvolvedor Mainframe deveria aprender EXPLAIN.

Ele responde perguntas como:

  • Qual índice será utilizado?

  • Quantas páginas serão lidas?

  • Haverá Tablespace Scan?

  • Será usado Hash Join?

  • Nested Loop?

  • Merge Join?

O EXPLAIN é uma janela para o cérebro do DB2.

Não basta escrever SQL correto.

É preciso entender como ele será executado.


JOIN não é apenas SQL

Muitos iniciantes acreditam que JOIN pertence exclusivamente ao SQL.

Na verdade...

JOIN é um conceito matemático.

Baseado em Álgebra Relacional.

Projetos.

Seleções.

Uniões.

Diferenças.

Interseções.

Produto Cartesiano.

Todos esses operadores são estudados muito antes do SQL existir.

SQL apenas transformou essas ideias em uma linguagem prática.


A evolução para Big Data

Mesmo tecnologias modernas continuam utilizando o conceito de JOIN.

Spark SQL.

Hive.

Snowflake.

BigQuery.

Databricks.

DuckDB.

PostgreSQL.

Oracle.

SQL Server.

Todos executam JOINs.

Mudam os algoritmos.

Mudam as otimizações.

Mas a teoria continua exatamente a mesma criada por Edgar Codd há mais de cinquenta anos.

Isso demonstra a força de uma boa ideia.


O que um Programador COBOL Padawan deve levar desta conversa?

Se você está começando sua jornada em informática, talvez pense que JOIN é apenas mais uma palavra da linguagem SQL.

Não é.

JOIN representa uma mudança de mentalidade.

No mundo procedural, típico de muitos programas COBOL tradicionais, você descreve passo a passo como localizar, ler e combinar registros. No mundo relacional, você descreve o que deseja obter, e o banco de dados decide a melhor estratégia para alcançar esse resultado.

Essa diferença parece sutil, mas muda completamente a forma de projetar sistemas.

Ao dominar JOINs, você deixa de enxergar tabelas como arquivos isolados e passa a vê-las como partes de uma grande rede de relacionamentos. É essa visão que permite construir consultas elegantes, sistemas escaláveis e aplicações capazes de responder rapidamente a perguntas complexas sobre milhões — ou até bilhões — de registros.

Da próxima vez que escrever um INNER JOIN, lembre-se de que não está apenas unindo duas tabelas. Está utilizando um dos conceitos mais elegantes da Álgebra Relacional, aperfeiçoado por décadas de pesquisa e otimizado continuamente pelos maiores bancos de dados do mundo.

E essa é uma das grandes lições da engenharia de software: as tecnologias evoluem, as linguagens mudam, o hardware se transforma, mas os fundamentos permanecem. Quem aprende esses fundamentos não está apenas estudando SQL; está construindo uma base sólida para compreender qualquer plataforma de dados, do IBM Z aos ambientes distribuídos em nuvem.

No Bellacosa Mainframe, costumamos dizer que um verdadeiro COBOL Padawan não coleciona apenas comandos. Ele coleciona maneiras diferentes de pensar. Porque, no fim das contas, programar nunca foi apenas escrever código. Programar é aprender a conversar com a lógica que organiza o mundo dos dados. E os JOINs são uma das linguagens mais poderosas dessa conversa.