| Bellacosa Mainframe apresenta Codd Db2 SQL e banco de dados relacional |
☕ Um Café no Bellacosa Mainframe
Edgar “Ted” Codd Toma Chá no Condado — O Dia em que os Dados Abandonaram o Labirinto, Aprenderam SQL e Descobriram que até uma Elegante Tabela Precisa de COMMIT
Ou: como o modelo relacional libertou o programador dos ponteiros, por que o Db2 não inventou tudo sozinho, o que ACID realmente significa e por que um SELECT * continua sendo falta de educação até numa confortável poltrona inglesa
Prólogo — Chá, biscoitos e um arquivo sequencial com 40 milhões de registros
Chovia delicadamente sobre um condado inglês cujo nome ninguém no CPD conseguia pronunciar corretamente.
Dentro de uma antiga casa de campo, Edgar Frank “Ted” Codd estava acomodado numa confortável poltrona de couro, diante de uma lareira acesa. Sobre a pequena mesa repousavam um bule de chá, biscoitos amanteigados, algumas folhas cobertas por símbolos matemáticos e, por algum acidente temporal que jamais seria explicado, um terminal 3270 conectado a um mainframe IBM.
Do outro lado da sala, um jovem programador COBOL examinava uma solicitação enviada pela Diretoria:
“Precisamos saber quantos clientes de cada cidade realizaram compras superiores a dez mil moedas nos últimos seis meses.”
O iniciante respirou fundo.
Abriu o arquivo mestre de clientes.
Abriu o arquivo de transações.
Procurou o copybook.
Descobriu que existiam quatro versões do copybook.
Uma estava num PDS chamado OLD.
Outra estava num PDS chamado OLD.BKP.
A terceira terminava com .NEW.
A quarta se chamava DEFINITIVA, o que, em ambientes corporativos, normalmente significa que não é definitiva.
— Vou precisar escrever um programa, classificar os registros, fazer um MATCH, gerar um arquivo intermediário e depois produzir o relatório — explicou o programador. — Talvez fique pronto na próxima semana.
Codd mexeu calmamente o chá.
— E se você pudesse apenas declarar qual resultado deseja?
O jovem olhou para o terminal.
— Sem dizer ao computador como percorrer cada arquivo?
— Exatamente.
— Isso parece magia.
Codd colocou o pires sobre a mesa.
— Não é magia. É matemática com um bom otimizador.
Naquele instante, em algum lugar do tempo, um gerente enviou uma mensagem dizendo que a alteração era pequena.
A chuva ficou mais forte.
1. Antes do banco relacional, os dados não viviam em cavernas
Contar essa história dizendo que, antes do modelo relacional, as empresas administravam seus dados como se usassem fichas de papel é uma boa imagem literária, mas uma explicação histórica incompleta.
As décadas de 1960 e 1970 já possuíam sistemas sofisticados de gerenciamento de dados. Empresas processavam folhas de pagamento, reservas de passagens, contas bancárias, estoques e milhões de transações sem usar SQL.
Um dos exemplos mais importantes é o IMS, o Information Management System da IBM. Ele nasceu no contexto do programa Apollo e tornou-se um dos grandes bancos de dados corporativos do mainframe.
O IMS trabalha com uma estrutura hierárquica. Para um iniciante, podemos imaginá-la como uma árvore:
CLIENTE
├── CONTA
│ ├── SALDO
│ └── LANÇAMENTO
└── CARTÃO
├── FATURA
└── COMPRAPara encontrar uma compra, a aplicação normalmente navega por um caminho previamente conhecido:
CLIENTE → CARTÃO → FATURA → COMPRAEsse modelo pode ser extremamente rápido. Se o caminho estiver bem definido e a aplicação souber exatamente aonde deseja chegar, a navegação é eficiente.
O problema aparece quando o negócio formula uma pergunta que não combina com os caminhos existentes.
Imagine que a empresa tenha organizado os dados para consultar todas as compras de determinado cliente. Depois, a Diretoria pergunta:
“Quais produtos foram comprados por clientes de três cidades diferentes durante uma promoção específica?”
Talvez essa navegação não tenha sido prevista.
Nesse caso, poderia ser necessário:
escrever um novo programa;
navegar por diferentes segmentos;
extrair informações para um arquivo;
ordenar os registros;
combinar arquivos;
criar índices adicionais;
executar um batch;
produzir um relatório;
esperar a janela de processamento.
O problema não era falta de inteligência dos programadores antigos. Muito pelo contrário: eles realizavam trabalhos extraordinários com memória, CPU e armazenamento limitados.
O problema era o acoplamento entre a pergunta, a estrutura lógica dos dados e o caminho físico utilizado para encontrá-los.
O programa precisava saber não apenas o que procurar, mas como chegar até lá.
2. Codd não queria apenas inventar uma tabela bonita
Edgar Frank Codd, conhecido como Ted Codd, era matemático e pesquisador da IBM. Em 1970, publicou o artigo:
A Relational Model of Data for Large Shared Data Banks.
Esse trabalho se tornou uma das bases mais importantes da computação moderna.
É comum resumir sua contribuição assim:
“Codd organizou os dados em tabelas com linhas e colunas.”
Não está errado, mas é semelhante a dizer que Alan Turing “trabalhava com fitas”. A descrição mostra a superfície e esconde a revolução.
Codd desejava criar uma fronteira clara entre:
a representação lógica dos dados;
a forma de consultá-los;
sua organização física dentro da máquina.
Em outras palavras, ele queria proteger o usuário e o programador da obrigação de conhecer todos os detalhes internos de armazenamento.
Antes, a aplicação podia precisar dizer:
“Comece pelo registro mestre, siga este ponteiro, abra aquele conjunto, leia o próximo segmento e continue até encontrar o código desejado.”
No modelo relacional, a aplicação poderia declarar:
SELECT NOME, SALDO
FROM CONTA
WHERE SALDO < 0;A pergunta descreve o resultado. Ela não determina detalhadamente o caminho físico.
Essa é a grande virada:
Modelo navegacional:
“Explique por onde devo caminhar.”
Modelo relacional:
“Explique qual resultado deseja.”O banco de dados recebe a responsabilidade de descobrir uma estratégia adequada.
Codd não estava apenas organizando registros. Ele estava propondo independência de dados.
3. Relação, tupla e atributo: a matemática entrou no CPD
Uma relação pode ser apresentada ao iniciante como uma tabela:
| CONTA | CLIENTE | AGÊNCIA | SALDO |
|---|---|---|---|
| 1001 | Ana | 120 | 5.500,00 |
| 1002 | Bruno | 120 | -320,00 |
| 1003 | Carla | 450 | 810,00 |
Na linguagem formal:
a tabela corresponde aproximadamente a uma relação;
cada linha é uma tupla;
cada coluna é um atributo;
o conjunto de valores permitidos para um atributo é seu domínio;
uma chave identifica uma tupla;
as restrições protegem a integridade dos dados.
Por que usamos “aproximadamente”?
Porque uma relação matemática não é simplesmente uma planilha. Ela possui propriedades formais. Não depende visualmente da ordem das linhas, não deveria conter tuplas duplicadas e representa um conjunto de fatos.
Considere:
SELECT CLIENTE, SALDO
FROM CONTA
WHERE SALDO < 0;Em linguagem humana, estamos pedindo:
“Forme uma relação contendo cliente e saldo para as tuplas nas quais o saldo seja negativo.”
Podemos combinar relações:
SELECT C.NOME,
P.NUMERO_PEDIDO,
P.VALOR
FROM CLIENTE C
JOIN PEDIDO P
ON P.ID_CLIENTE = C.ID_CLIENTE
WHERE P.VALOR > 10000;O JOIN não manda o computador seguir obrigatoriamente um ponteiro físico entre dois registros. Ele declara a condição lógica que relaciona as informações:
P.ID_CLIENTE = C.ID_CLIENTEO sistema pode escolher diferentes estratégias para produzir o resultado.
O programador passou a pensar mais sobre conjuntos, predicados e resultados — e menos sobre o endereço físico do próximo registro.
Isso não eliminou a necessidade de compreender arquivos, páginas, índices ou buffers. Apenas mudou quem deve decidir cada detalhe e em qual momento.
4. System R: quando a teoria precisou funcionar fora da poltrona
Uma teoria pode ser elegante enquanto toma chá ao lado da lareira. O problema começa quando alguém pede que ela processe a folha de pagamento.
Após o trabalho de Codd, a IBM iniciou o projeto System R em seu laboratório de San Jose. O objetivo era descobrir se um sistema relacional poderia ser construído de forma prática e com desempenho aceitável.
A pergunta era séria.
Muitos especialistas acreditavam que a flexibilidade do modelo relacional teria um custo alto demais. Um sistema navegacional já conhecia seus caminhos. Um banco relacional teria de receber uma pergunta abstrata e descobrir como executá-la.
O System R demonstrou que isso era possível.
O projeto trabalhou com conceitos que se tornariam fundamentais:
linguagem declarativa;
catálogo de metadados;
índices;
transações;
controle de concorrência;
recuperação;
autorização;
views;
compilação de consultas;
otimização baseada em custo;
escolha automática de caminhos de acesso.
O System R não foi simplesmente “o primeiro Db2”. Era um projeto experimental, uma oficina na qual muitas ideias foram construídas, testadas, descartadas ou aperfeiçoadas.
Seu valor histórico está em provar que o modelo relacional não era apenas uma bela teoria matemática. Poderia sustentar trabalho comercial de verdade.
Codd desenhou o mapa.
O System R colocou botas, capa de chuva e saiu para verificar se a estrada existia.
5. SEQUEL: o dia em que a consulta tentou falar inglês
Donald Chamberlin e Raymond Boyce desenvolveram uma linguagem para trabalhar com o System R. Inicialmente, ela foi chamada SEQUEL, de Structured English Query Language.
Mais tarde, o nome foi reduzido para SQL, Structured Query Language.
Isso explica por que algumas pessoas pronunciam “és-quiú-él” e outras dizem “sequel”. As duas pronúncias carregam pedaços da história.
Veja esta consulta:
SELECT NOME
FROM FUNCIONARIO
WHERE DEPARTAMENTO = 'CONTABILIDADE';Ela se aproxima de uma frase em inglês:
Selecione o nome do funcionário onde o departamento seja Contabilidade.
Não é linguagem natural. Não podemos conversar livremente com o banco como se ele fosse Jeeves, o mordomo da casa de campo. Porém, comparado às interfaces de baixo nível, era uma enorme aproximação da linguagem utilizada pelas pessoas.
O SQL é declarativo.
Você informa o que deseja, não necessariamente como executar.
Compare dois pensamentos.
Pensamento navegacional
Abra o arquivo de funcionários.
Leia o primeiro registro.
Verifique o departamento.
Se for Contabilidade, grave o nome.
Leia o próximo registro.
Repita até o fim.
Pensamento relacional
SELECT NOME
FROM FUNCIONARIO
WHERE DEPARTAMENTO = 'CONTABILIDADE';Parece simples porque alguém colocou uma enorme quantidade de engenharia atrás dessa simplicidade.
6. O otimizador: o mordomo invisível da mansão
O SQL diz o que queremos. Mas alguém ainda precisa decidir como encontrar o resultado.
Esse alguém é o otimizador.
Imagine duas tabelas:
CLIENTE 20 milhões de linhas
TRANSACAO 4 bilhões de linhasAgora execute:
SELECT C.NOME,
SUM(T.VALOR)
FROM CLIENTE C
JOIN TRANSACAO T
ON T.ID_CLIENTE = C.ID_CLIENTE
WHERE C.CIDADE = 'ITATIBA'
GROUP BY C.NOME;Existem várias estratégias possíveis:
ler todos os clientes;
usar um índice sobre cidade;
começar pelas transações;
começar pelos clientes selecionados;
usar um nested-loop join;
classificar valores;
utilizar paralelismo;
ler antecipadamente páginas;
empregar um índice composto;
criar resultados intermediários.
O otimizador examina informações como:
número estimado de linhas;
quantidade de páginas;
distribuição dos valores;
seletividade;
índices disponíveis;
organização dos objetos;
custos estimados de CPU e entrada/saída;
possibilidade de paralelismo;
ordem das tabelas no
JOIN.
Patricia Selinger e a equipe do System R tiveram papel decisivo na criação da otimização baseada em custo.
O otimizador é como um mordomo inglês eficiente. O visitante diz:
“Gostaria de chá.”
Ele não precisa explicar:
em qual armário está o bule;
qual torneira fornece água;
quanto tempo a água deve ser aquecida;
onde ficam as xícaras;
qual bandeja deve ser usada.
O mordomo escolhe o caminho.
Mas, se as informações estiverem erradas, talvez ele procure o chá na biblioteca e encontre apenas uma instalação antiga do IMS.
No Db2, estatísticas desatualizadas podem levar o otimizador a tomar decisões inadequadas. É por isso que existem utilitários e atividades como:
RUNSTATS;REORG;EXPLAIN;manutenção de índices;
análise do access path.
O SQL esconde detalhes. Ele não apaga as consequências físicas.
7. Db2: quando o modelo relacional entrou no MVS
Em 1983, a IBM lançou o Database 2, depois grafado Db2, para o ambiente MVS nos mainframes.
Às vezes se afirma que o Db2 foi o primeiro banco de dados relacional comercial. Isso não é correto.
Antes dele:
a IBM já havia lançado o SQL/DS;
a Oracle já comercializava um banco relacional;
o Ingres também participava dessa história.
O Db2 não precisa receber um troféu que pertence a uma história mais coletiva. Sua realização real já é gigantesca.
Ele levou a tecnologia relacional ao centro de ambientes MVS com exigências corporativas severas:
grande volume de dados;
muitas aplicações concorrentes;
processamento batch;
transações online;
recuperação;
segurança;
disponibilidade;
integridade;
auditoria;
compatibilidade;
administração centralizada.
O Db2 ajudou a demonstrar que uma base relacional podia cuidar de contas bancárias, reservas, pedidos, faturas e estoques sem desmaiar quando o laboratório se transformasse em produção.
Existe uma diferença enorme entre executar uma consulta numa demonstração e manter milhares de transações trabalhando enquanto o fechamento contábil, o CICS e o batch disputam recursos.
O mainframe foi a forja porque as ideias precisaram sobreviver ao mundo real.
8. ACID: não foi inventado pelo Db2, mas encontrou nele uma casa respeitável
Uma imprecisão comum é afirmar que o Db2 criou as propriedades ACID.
Os conceitos transacionais foram desenvolvidos durante vários anos e apareceram em sistemas anteriores. A formulação clássica do acrônimo ACID foi consolidada por Theo Härder e Andreas Reuter num importante artigo publicado também em 1983.
O Db2 não inventou sozinho o ACID. Entretanto, colocou essas propriedades em prática em um dos ambientes empresariais mais exigentes do mundo.
ACID significa:
Atomicidade;
Consistência;
Isolamento;
Durabilidade.
Vamos visitar cada cômodo da mansão.
8.1 Atomicidade — não existe meia transferência
Considere:
UPDATE CONTA
SET SALDO = SALDO - 500
WHERE NUMERO = 1001;
UPDATE CONTA
SET SALDO = SALDO + 500
WHERE NUMERO = 2002;
COMMIT;A transação possui duas atualizações:
retirar 500 da primeira conta;
acrescentar 500 à segunda.
Se o sistema executar somente o débito, teremos uma transferência pela metade.
Atomicidade significa que a unidade lógica é indivisível:
tudo acontece;
ou nada permanece.
Se uma etapa falhar antes da confirmação, o sistema deve desfazer o trabalho incompleto com ROLLBACK.
Atomicidade não significa que a transação seja pequena ou instantânea. Significa que seus efeitos são considerados como uma unidade.
8.2 Consistência — o banco não pode sair pela janela usando pantufas
Uma transação deve conduzir o banco de um estado válido para outro estado válido.
Algumas regras podem ser expressas pelo próprio banco:
SALDO DECIMAL(15,2) NOT NULLUma chave estrangeira pode impedir a existência de uma conta associada a um cliente inexistente. Uma constraint pode impedir determinado valor proibido. Uma chave primária pode evitar duplicidade.
Mas o SGBD não conhece telepaticamente todas as regras do negócio.
A empresa precisa definir:
constraints;
validações;
regras na aplicação;
triggers, quando apropriadas;
políticas de integridade;
tratamento de erros.
Se o negócio determina que um cliente menor de idade não pode contratar certo produto, alguém precisa transformar essa regra numa proteção técnica.
O Db2 protege aquilo que foi corretamente especificado. Ele não possui bola de cristal, embora alguns planos de execução pareçam ter sido escritos por Nostradamus.
8.3 Isolamento — dois caixas e o último saldo disponível
Imagine uma conta com saldo de 500.
Dois terminais consultam o valor quase simultaneamente:
Terminal A lê: 500
Terminal B lê: 500O Terminal A tenta sacar 500.
O Terminal B também tenta sacar 500.
Sem controle adequado, ambos poderiam acreditar que o dinheiro está disponível.
Isolamento controla a interferência entre transações concorrentes.
No Db2, o programador precisa conhecer conceitos como:
locks;
timeout;
deadlock;
cursor stability;
read stability;
repeatable read;
uncommitted read;
WITH UR;unidade de trabalho.
Isolamento demais pode produzir contenção. Isolamento de menos pode permitir comportamentos indesejáveis.
A escolha correta depende do negócio.
Uma consulta estatística talvez tolere uma leitura ainda não confirmada. Uma movimentação financeira normalmente exige proteções muito mais rigorosas.
Colocar WITH UR em tudo porque “fica mais rápido” é como remover as fechaduras da casa para economizar tempo ao entrar.
8.4 Durabilidade — depois do COMMIT, acabou a poesia
Quando o sistema informa que uma transação foi confirmada, seu resultado precisa sobreviver a falhas.
Se o cliente concluiu um pagamento e recebeu a confirmação, o banco não pode reiniciar e responder:
“Pedimos desculpas. O seu pagamento era apenas uma experiência temporária em memória.”
Logs, checkpoints e mecanismos de recuperação ajudam a fornecer durabilidade.
O COMMIT representa uma fronteira importante. Antes dele, o trabalho pode ser desfeito. Depois dele, o resultado confirmado precisa permanecer.
Por isso a frase merece ser gravada no pires de todo programador iniciante:
COMMITnão é pontuação estética. É uma decisão de negócio.
Um COMMIT cedo demais pode quebrar a atomicidade de uma operação maior. Um COMMIT tarde demais pode manter recursos e locks durante muito tempo.
9. Quando o SQL encontra o COBOL
O SQL não substituiu automaticamente o COBOL. No mainframe, eles frequentemente trabalham juntos.
Um programa pode conter SQL embutido:
EXEC SQL
SELECT NOME,
SALDO
INTO :WS-NOME,
:WS-SALDO
FROM CONTA
WHERE NUMERO_CONTA = :WS-NUMERO-CONTA
END-EXEC.Observe as variáveis precedidas por dois-pontos:
:WS-NOME
:WS-SALDO
:WS-NUMERO-CONTASão host variables: campos do programa COBOL utilizados para trocar valores com o Db2.
O compilador COBOL, sozinho, não entende toda a instrução SQL. Existe um processo que pode envolver:
preparação do fonte;
precompilação das instruções SQL;
criação do DBRM;
compilação COBOL;
link-edit;
BINDdo DBRM em um package;eventual ligação do package a uma collection ou plan;
execução.
O programa também precisa tratar resultados:
EVALUATE SQLCODE
WHEN 0
CONTINUE
WHEN +100
DISPLAY 'CONTA NAO ENCONTRADA'
WHEN OTHER
DISPLAY 'ERRO SQL: ' SQLCODE
END-EVALUATEPara o iniciante:
SQLCODE = 0normalmente indica sucesso;SQLCODE = +100normalmente indica que nenhuma linha foi encontrada ou que o cursor chegou ao fim;SQLCODEnegativo indica erro;SQLSTATEfornece uma representação padronizada da condição.
Ignorar o SQLCODE porque o programa compilou é como ignorar o alarme de incêndio porque a campainha possui uma melodia agradável.
10. Consulta única e cursor: chá para um ou banquete para muitos
Se uma consulta deve retornar apenas uma linha, podemos usar SELECT ... INTO.
Mas, quando várias linhas podem ser retornadas, normalmente utilizamos um cursor.
Exemplo conceitual:
EXEC SQL
DECLARE C1 CURSOR FOR
SELECT NOME,
SALDO
FROM CONTA
WHERE AGENCIA = :WS-AGENCIA
ORDER BY NOME
END-EXEC.Depois:
EXEC SQL
OPEN C1
END-EXEC.A aplicação busca cada linha:
EXEC SQL
FETCH C1
INTO :WS-NOME,
:WS-SALDO
END-EXEC.Ao final:
EXEC SQL
CLOSE C1
END-EXEC.O fluxo é:
DECLARE → OPEN → FETCH → FETCH → FETCH → CLOSEO cursor é semelhante a uma lista preparada pelo mordomo. O programa não recebe necessariamente todos os convidados de uma vez; solicita o próximo nome conforme avança.
É preciso tratar corretamente o SQLCODE +100, pois ele indica o fim do conjunto de resultados.
11. SELECT *: a bandeja grande demais
O comando abaixo é conveniente:
SELECT *
FROM CLIENTE
WHERE CPF = :WS-CPF;Entretanto, em aplicações, ele pode ser uma má escolha.
Problemas possíveis:
recupera colunas desnecessárias;
aumenta o tráfego interno;
cria dependência da estrutura da tabela;
reduz a clareza;
pode prejudicar estratégias envolvendo índices;
dificulta manutenção;
pode surpreender quando a tabela recebe novas colunas.
Prefira declarar o necessário:
SELECT NOME,
DATA_NASCIMENTO,
SITUACAO
FROM CLIENTE
WHERE CPF = :WS-CPF;No chá inglês, ninguém pede:
“Traga tudo o que houver na cozinha.”
Pede-se chá, leite, açúcar e dois biscoitos.
O mesmo princípio vale para o Db2.
12. O catálogo: quando o banco aprendeu a falar sobre si próprio
Um banco relacional não armazena somente dados de clientes, contas e produtos. Ele também guarda metadados, ou seja, dados sobre os próprios dados.
O catálogo contém informações sobre:
tabelas;
colunas;
tipos;
índices;
views;
packages;
privilégios;
tablespaces;
dependências;
estatísticas.
Isso permite responder a perguntas administrativas:
Quais colunas existem?
Qual índice atende esta tabela?
Quem possui determinada autorização?
Quais packages dependem deste objeto?
Quando as estatísticas foram atualizadas?
Qual é a cardinalidade estimada?
Que objetos podem ser afetados por uma alteração?
O catálogo transformou o banco num sistema capaz de descrever a própria estrutura.
Ferramentas modernas de governança, geração de código, descoberta de dados e administração continuam explorando esse princípio.
O banco de dados ganhou um espelho — e, como todo sistema antigo, às vezes não gostou do que viu depois de quinze anos sem RUNSTATS.
13. Passo a passo para o iniciante pensar como Codd sem esquecer que trabalha no CPD
Passo 1 — Entenda a pergunta de negócio
Antes de escrever SQL, descubra:
o que precisa ser retornado;
qual é o período;
quais filtros se aplicam;
quantas linhas são esperadas;
se duplicidades são permitidas;
qual precisão é necessária;
se a consulta apenas lê ou também altera dados.
Uma consulta tecnicamente perfeita pode responder à pergunta errada.
Passo 2 — Identifique as relações necessárias
Pergunte:
Em qual tabela está o cliente?
Onde estão as contas?
Como as tabelas se relacionam?
Qual coluna representa a chave?
Existe histórico?
Uma conta pode ter mais de um titular?
Não invente relacionamentos observando nomes parecidos.
COD-CLI e ID-CLIENTE podem representar a mesma coisa — ou podem ser duas entidades distintas criadas depois de uma aquisição em 1997.
Passo 3 — Escreva o resultado mínimo
Evite buscar dados que não serão utilizados.
SELECT C.NOME,
SUM(T.VALOR)
FROM CLIENTE C
JOIN TRANSACAO T
ON T.ID_CLIENTE = C.ID_CLIENTE
WHERE T.DATA_TRANSACAO BETWEEN :WS-DATA-INICIAL
AND :WS-DATA-FINAL
GROUP BY C.NOME;Passo 4 — Teste casos normais e extremos
Teste:
nenhuma linha;
uma linha;
várias linhas;
valores nulos;
duplicidades;
datas-limite;
valores máximos;
caracteres especiais;
condições de erro.
Passo 5 — Examine o caminho de acesso
Use EXPLAIN e ferramentas disponíveis no ambiente.
Descubra:
se o índice foi utilizado;
se houve tablespace scan;
qual foi a ordem do join;
qual cardinalidade foi estimada;
se as estatísticas estão atualizadas.
Passo 6 — Planeje a unidade de trabalho
Determine:
onde começa a transação;
onde ocorre o
COMMIT;quando executar
ROLLBACK;quais recursos permanecem bloqueados;
o que fazer em caso de deadlock ou timeout.
Passo 7 — Trate todos os retornos
Não trate apenas o caminho feliz.
Um programa de produção precisa saber responder a:
linha inexistente;
duplicidade inesperada;
violação de integridade;
indisponibilidade;
deadlock;
timeout;
erro de autorização;
falha no package;
dado incompatível com a host variable.
Passo 8 — Meça
Não declare que a consulta está rápida porque funcionou com dez linhas no ambiente de desenvolvimento.
Produção pode possuir:
bilhões de linhas;
concorrência;
cache diferente;
estatísticas diferentes;
índices diferentes;
distribuição desigual;
cargas batch simultâneas.
O laboratório é uma xícara. A produção é o oceano onde o bule caiu.
14. O que PostgreSQL, Oracle, SQL Server, MySQL e Snowflake herdaram
Quando usamos SQL nesses produtos, estamos trabalhando com ideias cuja genealogia passa por Codd, System R e SEQUEL.
A herança inclui:
relações;
tabelas;
linhas e colunas;
chaves;
joins;
constraints;
views;
consultas declarativas;
catálogos;
transações;
otimizadores.
Isso não significa que todos sejam cópias do Db2.
Cada produto possui sua história, arquitetura e implementação:
PostgreSQL descende do projeto POSTGRES;
Oracle criou sua própria linha comercial;
Microsoft SQL Server desenvolveu seu próprio ecossistema;
MySQL adotou motores e escolhas particulares;
Snowflake utiliza SQL sobre uma arquitetura distribuída orientada à nuvem.
A herança é conceitual e linguística. Não é necessariamente uma linhagem direta de código-fonte.
É semelhante ao latim: português, espanhol, italiano e francês compartilham raízes, mas não são o mesmo idioma nem funcionam de maneira idêntica.
Codd ajudou a criar a gramática intelectual. Diferentes empresas construíram suas próprias cidades sobre esse território.
15. O mainframe é realmente a fonte de todas as tecnologias?
A frase “The Fountain From Which All Other Technologies Flow” é uma excelente provocação, mas deve ser tratada como metáfora.
Nem tudo nasceu no mainframe.
A computação moderna também recebeu contribuições decisivas de:
universidades;
laboratórios governamentais;
empresas concorrentes;
sistemas Unix;
redes acadêmicas;
computadores pessoais;
projetos de código aberto;
telecomunicações;
centros de pesquisa internacionais.
Entretanto, o mainframe foi uma das grandes forjas da computação empresarial.
Foi nele que muitas ideias precisaram aprender a conviver com:
dinheiro real;
milhares de usuários;
auditoria;
falhas;
concorrência;
segurança;
processamento contínuo;
compatibilidade por décadas;
consequências jurídicas e financeiras.
No laboratório, uma falha produz um relatório.
Num banco, ela pode produzir um saldo incorreto.
Numa companhia aérea, pode vender o mesmo assento duas vezes.
No varejo, pode reduzir o estoque sem confirmar a venda.
O mainframe ensinou uma lição que retorna em todas as gerações tecnológicas:
Uma tecnologia não está madura apenas quando funciona. Ela está madura quando falha de maneira controlada, recupera-se corretamente e preserva aquilo que já havia confirmado.
Epílogo — O último COMMIT antes da chuva parar
O jovem programador COBOL terminou sua consulta:
SELECT C.CIDADE,
COUNT(DISTINCT C.ID_CLIENTE) AS CLIENTES,
SUM(P.VALOR) AS VALOR_TOTAL
FROM CLIENTE C
JOIN PEDIDO P
ON P.ID_CLIENTE = C.ID_CLIENTE
WHERE P.DATA_PEDIDO >= :WS-DATA-LIMITE
AND P.VALOR > 10000
GROUP BY C.CIDADE
ORDER BY VALOR_TOTAL DESC;Codd observou a tela.
— Muito melhor — disse ele.
— Então não preciso mais conhecer arquivos, índices, buffers, locks ou caminhos de acesso?
Codd interrompeu a xícara antes que ela tocasse os lábios.
O silêncio tomou a sala.
Até o terminal 3270 pareceu escurecer.
— Meu jovem, eu lhe dei independência de dados. Não lhe dei licença para ignorar o computador.
O programador abriu o EXPLAIN.
Descobriu um tablespace scan sobre bilhões de linhas.
As estatísticas estavam desatualizadas.
O índice que todos juravam existir havia sido removido durante uma mudança emergencial três anos antes.
No catálogo, o responsável pela alteração aparecia como USER01.
Ninguém conhecia USER01.
Na lareira, uma chama assumiu por um instante a forma de uma mensagem:
DSNT408I SQLCODE = -911Era o easter egg deixado pelo fantasma de uma transação vítima de deadlock.
Depois de corrigir a consulta, atualizar as estatísticas e testar a unidade de trabalho, o jovem executou novamente o programa.
O relatório apareceu.
Os saldos permaneceram corretos.
O COMMIT foi realizado no momento adequado.
Codd finalmente bebeu o chá.
Conclusão — Os dados não aprenderam apenas uma linguagem
Edgar F. Codd não inventou simplesmente uma maneira conveniente de desenhar tabelas. Ele ajudou a mudar a relação entre pessoas, programas e dados.
O modelo relacional ofereceu:
independência entre lógica e armazenamento;
uma base matemática;
operações sobre conjuntos;
consultas declarativas;
maior flexibilidade para formular novas perguntas;
um terreno comum para linguagens como SQL.
O System R demonstrou que a teoria poderia funcionar.
SEQUEL, depois SQL, deu aos dados uma linguagem declarativa.
O SQL/DS iniciou a transformação em produto dentro da IBM.
O Db2 levou essa herança ao coração do MVS e das cargas empresariais críticas.
O mainframe submeteu tudo à pressão de bancos, companhias aéreas, governos, seguradoras e varejistas que não poderiam aceitar um resultado “aproximadamente correto”.
O Db2 não inventou sozinho o banco relacional, não foi o primeiro produto comercial dessa categoria e não criou isoladamente o ACID. Reconhecer essas nuances não reduz sua importância. Ao contrário: permite enxergar sua verdadeira grandeza.
Codd forneceu o modelo.
Chamberlin e Boyce ajudaram a criar a linguagem.
Selinger e sua equipe ensinaram o sistema a escolher caminhos.
Härder e Reuter consolidaram o vocabulário do ACID.
Muitos engenheiros transformaram pesquisa em produto.
E o mainframe colocou tudo diante do teste definitivo:
Funciona em produção, sob concorrência, depois de uma falha, sem perder o dinheiro de ninguém?
Quando hoje escrevemos:
SELECT *
FROM HISTORIA
WHERE TECNOLOGIA = 'MODERNA';encontramos cloud, PostgreSQL, Oracle, SQL Server, MySQL, data warehouses e plataformas distribuídas.
Mas, se acrescentarmos:
AND ORIGEM_CONCEITUAL = 'MODELO RELACIONAL';Ted Codd ainda estará lá, tomando chá numa confortável poltrona inglesa, olhando discretamente para o otimizador e lembrando ao programador COBOL:
Diga ao banco o que você deseja. Depois verifique com muito cuidado o que ele decidiu fazer.