Dados: Arquitetura, Engenharia e SQL

P2 · 10 questões × peso 3 = 30 pontos · prioridade: máxima
Visão do professorMinha recomendação é combinar comparação de conceitos e execução manual de consultas pequenas. Comece pelo grão da fato, pelos filtros/agregações e por JOINs/janelas; avance para arquiteturas, normalização e processamento distribuído. Não decore apenas que uma tecnologia é “melhor”: explique para qual carga e sob quais condições. NULL, multiplicação de linhas e manutenção de histórico merecem treino especial. O retorno por hora depende da sua base e dos seus erros, não de uma classificação universal da matéria.

Entenda do zero · Dados, Engenharia e SQL

Pense no caminho de uma informação: ela nasce em um sistema, é guardada, preparada e consultada. Os nomes técnicos descrevem partes desse caminho.

1. O que é um banco de dados?

É uma coleção organizada de dados. Em um banco relacional, uma tabela pode guardar contribuintes: cada linha representa um registro e cada coluna, uma característica. A chave primária identifica cada registro sem duplicidade; uma chave estrangeira faz referência a uma chave de outra tabela, ou da própria tabela, ajudando a manter os relacionamentos válidos.

2. Por que separar tabelas?

Imagine repetir o nome e o endereço de um contribuinte em todas as suas notas fiscais. Uma mudança de endereço exigiria várias atualizações. A normalização organiza as informações para reduzir redundâncias e anomalias. Uma tabela de notas pode guardar o identificador do contribuinte, e a consulta combina os dados por meio de um JOIN.

3. SQL é uma forma de fazer perguntas aos dados

SELECT indica o que mostrar; FROM, de onde vêm os registros; WHERE filtra linhas; GROUP BY reúne linhas em grupos; SUM soma valores. Leia a consulta como uma pergunta, não como uma sequência de palavras para decorar.

Na prática · quanto foi arrecadado por município?
SELECT municipio, SUM(valor) AS total
FROM arrecadacao
WHERE ano = 2026
GROUP BY municipio;

A consulta considera os registros de 2026 e retorna uma linha para cada município, com a soma de seus valores. Não retorna cada pagamento individual.

4. Operar o dia a dia é diferente de analisar o histórico

Um sistema OLTP registra operações, como um pagamento. Uma solução OLAP favorece análises, como comparar arrecadação ao longo dos anos. O Data Warehouse (DW) integra dados para análise; o Data Lake aceita dados em formatos variados. ETL extrai, transforma e carrega; ELT carrega antes de transformar no ambiente de destino.

Confira se entendeu: para trazer também contribuintes sem notas, basta um INNER JOIN?

Não. O INNER JOIN mantém apenas as correspondências. Um LEFT JOIN partindo de contribuintes pode manter todos eles, com NULL nos campos sem correspondência; filtros posteriores precisam preservar essa intenção.

A seguir, compare as arquiteturas e aprofunde a leitura de SQL.

Tipos de dados e Big Data

TipoCaracterísticaExemplos
EstruturadoEsquema rígido e prévio (linhas e colunas), schema-on-writeTabelas de SGBD relacional, planilha bem formada
SemiestruturadoEsquema embutido/autodescritivo (tags, chaves), flexívelJSON, XML, YAML, CSV com cabeçalho, logs com campos, NF-e em XML
Não estruturadoSem modelo de dados predefinidoTexto livre, PDF digitalizado, imagem, áudio, vídeo, e-mail (corpo)
Pegadinha FCCXML e JSON são semiestruturados, não "não estruturados". E e-mail é misto: cabeçalho (remetente, data) é semiestruturado; corpo é não estruturado.

Os Vs do Big Data

Mnemônico"VoVeVa + VeVa": Volume, Velocidade, Variedade (os clássicos) + Veracidade, Valor. Se a questão fala em "3 Vs", são só os três primeiros.

Processamento distribuído: Hadoop

Mnemônico"HMY" = HDFS guarda, MapReduce processa, YARN gerencia recursos. "Guarda, processa, gerencia".

Apache Spark e PySpark

TransformaçãoAção
Preguiçosa (lazy): só registra no plano, não executaDispara a execução do DAG
Retorna novo RDD/DataFrameRetorna valor ao driver ou grava
select, filter/where, withColumn, groupBy, join, mapcount, collect, show, take, write, first
from pyspark.sql import SparkSession, functions as F
spark = SparkSession.builder.appName("icms").getOrCreate()
df = spark.read.parquet("/lake/silver/nfe")          # transformação (lazy)
res = (df.filter(F.col("uf") == "SP")                 # narrow
         .groupBy("cnae")                             # wide (shuffle)
         .agg(F.sum("valor").alias("total")))
res.show()                                            # AÇÃO: aqui executa
Pegadinha FCC"Ao executar df.filter(...) o Spark processa imediatamente os dados" — errado. Nada roda até uma ação. Outra: collect() traz todos os dados para o driver — em base grande, estoura memória; para espiar, use show() ou take(n).
BizuTolerância a falhas do Spark vem da linhagem (o RDD sabe recomputar a partição perdida a partir das transformações), e não de replicar tudo em disco como o HDFS. cache()/persist() guardam em memória um resultado reutilizado.

Arquiteturas: DW, Data Mart, Data Lake, Lakehouse

Data Warehouse (Inmon)

Definição clássica (Inmon)Data Warehouse é uma coleção de dados orientada por assunto, integrada, variante no tempo e não volátil, que dá suporte ao processo de tomada de decisão gerencial.
Mnemônico"TINO" do DW: Tempo (variante no tempo — guarda histórico, tempo faz parte da chave), Integrado (padroniza nomes, códigos e unidades), Não volátil (carga e consulta; não há update/delete transacional), Orientado por assunto (vendas, arrecadação, e não por aplicação).
InmonKimball
AbordagemTop-downBottom-up
NúcleoEDW corporativo normalizado (3FN)Data marts dimensionais (estrela)
Data martsDependentes, derivados do EDWSão o próprio DW, integrados pelo barramento (bus) com dimensões conformadas
EntregaMais lenta, mais integrada desde o inícioMais rápida, incremental
Pegadinha FCCTrocar os autores: "Kimball propõe um DW corporativo normalizado do qual derivam data marts" — errado, isso é Inmon. Kimball = dimensional, bottom-up, matriz de barramento.

Data Mart

Comparativo das arquiteturas

Data WarehouseData LakeData Lakehouse
DadosEstruturados, tratadosTodos os tipos, brutos (formato nativo)Todos os tipos
EsquemaSchema-on-writeSchema-on-readAmbos (com imposição e evolução de esquema)
ArmazenamentoSGBD analítico (custo maior)Object storage barato (S3, ADLS, HDFS)Object storage + formato de tabela aberto (Delta Lake, Apache Iceberg, Apache Hudi)
Transações ACIDSimEm geral nãoSim (via camada de metadados/log de transações)
Usuário típicoAnalista de negócio, BICientista/engenheiro de dadosAmbos: BI e ciência de dados na mesma cópia
RiscoRigidez, custoVirar data swamp (pântano) sem governança/catálogoComplexidade de plataforma
BizuLakehouse = "lago com cara de armazém": dados no lago barato + recursos de DW (ACID, esquema, versionamento/time travel, desempenho para SQL/BI). Se a alternativa menciona Delta Lake, Iceberg ou Hudi, pense Lakehouse.

Arquitetura medalhão (medallion)

Mnemônico"Bruto, Bonito, Business": Bronze = bruto; Prata = bonito (limpo); Ouro = pronto para o business.
Pegadinha FCC"No Data Lake os dados devem ser transformados antes da carga para obedecer ao esquema" — errado: isso é schema-on-write (DW). Lake armazena bruto e aplica esquema na leitura.

Engenharia de dados: pipelines, ETL e ELT

ETLELT
OrdemExtrai → Transforma (servidor/ferramenta intermediária, área de staging) → CarregaExtrai → Carrega bruto no destino → Transforma dentro do destino
Onde transformaFora do destino (motor de ETL)No próprio DW/Lakehouse (poder de processamento escalável, SQL)
Combina comDW tradicional on-premises, dados sensíveis que precisam ser tratados antesNuvem, Data Lake/Lakehouse, big data
Dado brutoNormalmente não fica disponívelFica disponível para reprocessar

Tratamento, limpeza e preparação

TécnicaO que faz
LimpezaTratar ausentes (remover, imputar média/mediana/moda), corrigir erros de digitação, padronizar formatos (datas, CPF)
DeduplicaçãoEliminar registros repetidos (garante unicidade)
Tratamento de outliersDetectar (IQR, z-score) e decidir: corrigir, remover, limitar (winsorizar) ou manter
EnriquecimentoAgregar informação externa/complementar (ex.: CNPJ → CNAE e município)
Normalização (escala)Min-max: leva a [0,1]; padronização z-score: média 0, desvio 1
Discretização / codificaçãoFaixas (binning); one-hot para categóricas
IntegraçãoUnir fontes resolvendo conflitos de nomes, chaves e unidades
Pegadinha FCC"Normalização" tem dois sentidos: em banco de dados é decompor tabelas para eliminar redundância (formas normais); em pré-processamento é ajustar a escala numérica (min-max). Leia o contexto do enunciado.

Qualidade de dados (dimensões)

DimensãoPerguntaExemplo de falha
CompletudeEstá tudo preenchido?CNPJ em branco
UnicidadeExiste uma só vez?Contribuinte cadastrado duas vezes
ValidadeObedece à regra/formato/domínio?Data 31/02; UF "XX"
AcuráciaCorresponde à realidade?Endereço válido, mas errado
ConsistênciaBate entre sistemas/campos?Total da nota diferente da soma dos itens
Tempestividade/atualidadeEstá disponível a tempo/atualizado?Cadastro desatualizado há 2 anos
BizuValidade x acurácia: um CPF com dígito verificador correto é válido, mas só é acurado se for o CPF da pessoa certa. A FCC adora essa distinção.

Batch x Streaming

Lote (batch)Fluxo (streaming)
DadosConjunto limitado (bounded), acumuladoFluxo contínuo e ilimitado (unbounded)
LatênciaAlta (minutos a horas)Baixa (milissegundos a segundos)
UsoCargas noturnas do DW, fechamento mensalDetecção de fraude, monitoramento, IoT, alertas
FerramentasSpark batch, MapReduce, SQL agendadoApache Kafka (mensageria/log de eventos), Spark Structured Streaming (micro-batch), Apache Flink

Janelas em streaming

Arquitetura LambdaArquitetura Kappa
Duas trilhas: batch layer (precisão) + speed layer (tempo real) + serving layerUma trilha só: tudo é streaming; reprocessa reproduzindo o log de eventos
Desvantagem: duas bases de códigoMais simples de manter
MnemônicoLambda tem duas pernas (a letra λ tem duas hastes: batch + velocidade). Kappa é "K de um caminho só" (streaming).
BizuSemântica de entrega: at-most-once (pode perder, nunca duplica), at-least-once (nunca perde, pode duplicar), exactly-once (nem perde nem duplica). No Kafka, as mensagens ficam em tópicos divididos em partições; o consumidor controla sua posição pelo offset.

Modelagem relacional e normalização

Forma normalRegra
1FNValores atômicos; sem grupos repetitivos/atributos multivalorados
2FN1FN + sem dependência parcial (atributo não chave depende de toda a chave composta)
3FN2FN + sem dependência transitiva (não chave dependendo de outro não chave)
FNBC (Boyce-Codd)Todo determinante é chave candidata
4FNFNBC + sem dependência multivalorada não trivial
5FN4FN + sem dependência de junção não trivial
MnemônicoO juramento clássico: cada atributo depende "da chave (1FN), da chave inteira (2FN) e de nada além da chave (3FN)".
Pegadinha FCC"Tabela com chave primária simples (uma coluna) que está na 1FN pode violar a 2FN" — errado: dependência parcial só existe com chave composta. Logo, 1FN + PK simples já está na 2FN.
BizuOLTP gosta de normalização (evita anomalias de inserção, atualização e exclusão). DW/BI desnormaliza de propósito (menos junções, consulta mais rápida). Desnormalizar no DW não é erro.

Modelagem dimensional

MnemônicoOs 4 passos de Kimball: "Pro-Grão-Di-Fa" = escolher o Processo de negócio → declarar o Grão → identificar as Dimensões → identificar os Fatos. Grão vem antes de dimensões e fatos.

Estrela x Floco de neve x Constelação

Estrela (star)Floco de neve (snowflake)Constelação (galáxia)
DimensõesDesnormalizadas, ligadas direto à fatoNormalizadas em subdimensõesVárias fatos compartilhando dimensões conformadas
JunçõesPoucasMais junções—
Desempenho/simplicidadeMelhorPior consulta, economiza espaço—

Tipos de métricas e de fatos

Tipos especiais de dimensão

SCD — Slowly Changing Dimensions

TipoTécnicaHistórico
0Mantém o valor original, ignora mudançaSó o original
1SobrescreveNenhum
2Nova linha com nova surrogate key + datas de vigência / flag de atualCompleto
3Nova coluna (valor anterior / atual)Limitado (só o anterior)
4Mini-dimensão / tabela de histórico separadaSeparado
6Híbrido 1 + 2 + 3Completo + valor atual em todas as linhas
Mnemônico"1 apaga, 2 duplica a linha, 3 cria coluna". Tipo 2 = 2 linhas para o mesmo contribuinte (antes e depois). Tipo 6 = 1+2+3 (e 1×2×3 = 6).
Pegadinha FCC"No SCD tipo 2 o registro existente é atualizado com o novo valor" — errado (isso é tipo 1). No tipo 2, a linha antiga é encerrada (data fim/flag) e uma nova linha é inserida.

OLTP x OLAP e operações OLAP

OLTP (transacional)OLAP (analítico)
ObjetivoOperação do dia a diaAnálise e decisão
OperaçõesINSERT/UPDATE/DELETE curtos e frequentesLeituras complexas, agregações sobre grande volume
ModeloNormalizado (3FN)Dimensional (estrela), desnormalizado
DadosAtuaisHistóricos
UsuáriosMuitos, operacionaisPoucos, analistas/gestores
OperaçãoO que faz
Drill-downDesce na hierarquia (ano → mês): mais detalhe
Roll-up (drill-up)Sobe na hierarquia / agrega: menos detalhe
SliceFixa um valor de uma dimensão (fatia: só 2025)
DiceSeleciona faixas em duas ou mais dimensões (subcubo)
Pivot (rotação)Gira os eixos da visualização
Drill-acrossNavega entre cubos/fatos diferentes por dimensões conformadas
Drill-throughVai do cubo até o dado detalhado de origem
Pegadinha FCCSlice x Dice: slice = uma dimensão fixada (reduz a dimensionalidade); dice = subcubo com filtros em várias dimensões. E drill-across ≠ drill-through.
MOLAPROLAPHOLAPDOLAP
Cubo multidimensional pré-calculado: rápido, menos escalávelSobre banco relacional (SQL): escalável, mais lentoHíbrido: agregados em MOLAP, detalhe em ROLAPDesktop: cubo baixado para a máquina do usuário

Bancos relacionais, colunares e NoSQL

ACID (relacional)BASE (muitos NoSQL)
Atomicidade: tudo ou nadaBasically Available: basicamente disponível
Consistência: transação leva de um estado válido a outro válidoSoft state: estado pode mudar sem nova entrada (replicação)
Isolamento: transações concorrentes não se enxergam pela metadeEventually consistent: converge com o tempo
Durabilidade: confirmado (commit) não se perde
MnemônicoQuímica: ácido x base são opostos — ACID prioriza consistência forte; BASE prioriza disponibilidade e escala, aceitando consistência eventual.

Teorema CAP (Brewer)

Pegadinha FCCO "C" do CAP (todos os nós veem o mesmo dado) não é o mesmo "C" do ACID (respeito às regras de integridade). Mesma letra, conceitos diferentes.

Tipos de NoSQL

TipoModeloUso típicoExemplos
Chave-valorChave → valor opacoCache, sessão, carrinhoRedis, Amazon DynamoDB, Riak
DocumentoDocumentos JSON/BSON aninhados, esquema flexívelCatálogos, cadastros variáveis, APIsMongoDB, CouchDB
Família de colunas (wide-column)Linhas com conjuntos variáveis de colunas agrupadas em famíliasEscrita massiva, séries temporais, IoTApache Cassandra, HBase
GrafoNós, arestas e propriedadesRedes de relacionamento, fraude (laranjas, grupos econômicos)Neo4j, Amazon Neptune
Mnemônico"CDCG — Chave, Documento, Coluna, Grafo": "Cada Dado Com seu Gaveteiro". Exemplos-âncora: Redis, Mongo, Cassandra, Neo4j.

Banco colunar (analítico)

Pegadinha FCCColunar analítico ≠ família de colunas. Cassandra/HBase são NoSQL wide-column, voltados a escrita distribuída; Redshift/BigQuery/Parquet são armazenamento colunar para análise. E NoSQL significa "Not only SQL", não "sem SQL".
BizuEscalabilidade: relacional tradicional escala melhor verticalmente (máquina maior); NoSQL foi pensado para escalar horizontalmente (mais máquinas, sharding). NewSQL (ex.: CockroachDB, Google Spanner) tenta unir SQL + ACID + escala horizontal.

SQL: sublinguagens e comandos

SublinguagemComandos
DDL (definição)CREATE, ALTER, DROP, TRUNCATE, RENAME
DML (manipulação)INSERT, UPDATE, DELETE, MERGE
DQL (consulta)SELECT (muitos autores o põem na DML)
DCL (controle)GRANT, REVOKE (DENY no SQL Server)
TCL (transação)COMMIT, ROLLBACK, SAVEPOINT
MnemônicoDCL = "Dá e Cassa Licença": GRANT dá, REVOKE cassa. DDL mexe na Definição (a "casa"); DML mexe na Mobília (os dados).
DELETETRUNCATEDROP
CategoriaDMLDDLDDL
RemoveLinhas (todas ou com WHERE)Todas as linhas, sem WHEREA tabela inteira (estrutura + dados + índices)
EstruturaMantémMantémSome
Triggers de DELETEDisparamNão disparam—
DesempenhoMais lento (registra linha a linha)Rápido (desaloca páginas)Rápido
Pegadinha FCC"TRUNCATE nunca pode ser desfeito" depende do SGBD: no Oracle faz commit implícito (DDL); no SQL Server e no PostgreSQL pode ser revertido dentro de uma transação explícita. Afirmações absolutas sobre isso são perigosas. Já "TRUNCATE aceita cláusula WHERE" é sempre errado.

Restrições (constraints)

PRIMARY KEY, FOREIGN KEY ... REFERENCES (com ON DELETE CASCADE / SET NULL / NO ACTION), UNIQUE (aceita NULL, conforme SGBD), NOT NULL, CHECK, DEFAULT.

SQL: consulta (DQL), agregação e filtros

Ordem lógica de execução

EscritaExecução lógica
1. SELECT
2. FROM / JOIN
3. WHERE
4. GROUP BY
5. HAVING
6. ORDER BY
7. LIMIT/TOP
1. FROM / JOIN
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT (e DISTINCT)
6. ORDER BY
7. LIMIT/OFFSET/TOP
Mnemônico"Fala, Wesley: Gente Honesta Sempre Ordena Limites" = FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY, LIMIT. Consequência: alias do SELECT não pode ser usado no WHERE (ainda não existe), mas pode no ORDER BY.
WHEREHAVING
Filtra linhas, antes do agrupamentoFiltra grupos, depois do GROUP BY
Não aceita função de agregaçãoAceita agregação (HAVING SUM(v) > 1000)
SELECT   c.uf, COUNT(*) AS qtd, SUM(n.valor_icms) AS total
FROM     nfe n
JOIN     contribuinte c ON c.id = n.id_contrib
WHERE    n.dt_emissao >= '2026-01-01'        -- filtra linhas
GROUP BY c.uf
HAVING   SUM(n.valor_icms) > 1000000         -- filtra grupos
ORDER BY total DESC;                          -- alias permitido aqui

Funções de agregação e NULL

Pegadinha FCCWHERE x NOT IN (SELECT y FROM t): se a subconsulta retornar algum NULL, o resultado é vazio. NOT EXISTS não sofre esse efeito.

Filtros e operadores lógicos

BizuEm questão de "qual o resultado", faça na ordem lógica: monte o FROM/JOIN, risque linhas pelo WHERE, forme os grupos, risque grupos pelo HAVING, e só então calcule o SELECT. Erra-se muito tentando ler de cima para baixo.

SQL: junções, conjuntos, subconsultas e janelas

JOINRetorna
INNER JOINSó as linhas com correspondência nas duas tabelas
LEFT (OUTER) JOINTodas da esquerda + correspondentes da direita (NULL onde não há par)
RIGHT (OUTER) JOINTodas da direita + correspondentes da esquerda
FULL (OUTER) JOINTodas de ambas, com NULL onde não há par
CROSS JOINProduto cartesiano (m × n linhas)
SELF JOINTabela unida a ela mesma (ex.: servidor e chefe)
NATURAL JOINJunção automática pelas colunas de mesmo nome
-- Anti-join: contribuintes SEM nenhuma nota emitida
SELECT c.id, c.razao
FROM   contribuinte c
LEFT JOIN nfe n ON n.id_contrib = c.id
WHERE  n.id_contrib IS NULL;
Pegadinha FCCLEFT JOIN com filtro sobre a tabela da direita no WHERE (ex.: WHERE n.ano = 2026) elimina as linhas com NULL e transforma o resultado, na prática, em INNER JOIN. Para preservar o "left", ponha a condição no ON.

Operações de conjunto

Subconsultas e CTE

Funções de janela (window functions)

SELECT uf, municipio, arrecadacao,
       ROW_NUMBER() OVER (PARTITION BY uf ORDER BY arrecadacao DESC) AS rn,
       RANK()       OVER (PARTITION BY uf ORDER BY arrecadacao DESC) AS rk,
       DENSE_RANK() OVER (PARTITION BY uf ORDER BY arrecadacao DESC) AS drk,
       LAG(arrecadacao) OVER (ORDER BY mes) AS mes_anterior
FROM   arrecadacao_municipio;
Valores empatadosROW_NUMBERRANKDENSE_RANK
100, 90, 90, 801, 2, 3, 41, 2, 2, 4 (pula)1, 2, 2, 3 (não pula)
BizuJanela não reduz linhas (ao contrário do GROUP BY): cada linha recebe o cálculo do seu grupo. LAG olha a linha anterior; LEAD, a próxima. GROUP BY ROLLUP gera subtotais hierárquicos; CUBE gera subtotais de todas as combinações.

Variações (dialetos) do SQL

RecursoSQL Server (T-SQL)Oracle (PL/SQL)PostgreSQL / MySQL
Limitar linhasSELECT TOP 10FETCH FIRST 10 ROWS ONLY (ou ROWNUM)LIMIT 10
Diferença de conjuntosEXCEPTMINUSEXCEPT (PostgreSQL)
Linguagem proceduralT-SQLPL/SQLPL/pgSQL (PostgreSQL)

No ecossistema big data: Spark SQL, HiveQL (Hive sobre Hadoop) e SQL em motores distribuídos (Presto/Trino) — SQL sobre arquivos do lago.

Análise de dados: EDA, mineração e analytics

KDD e mineração de dados

Pegadinha FCC"Data mining e KDD são sinônimos exatos" — para a banca, normalmente errado: mineração é a etapa de descoberta de padrões dentro do processo KDD. E "agrupamento exige rótulos prévios" — errado, clustering é não supervisionado.
BizuAnalytics em 4 níveis (Gartner): descritiva (o que aconteceu?), diagnóstica (por que aconteceu?), preditiva (o que vai acontecer?), prescritiva (o que fazer?). Detalhes na página de BI.

Governança técnica: metadados, catálogo e MDM

Mnemônico"Dono decide, Steward cuida, Custodiante guarda".
Pegadinha FCC"O custodiante de dados (TI) é quem define as regras de negócio e quem pode acessar o dado" — errado: isso é do owner. O custodiante implementa e opera os controles.

Teste rápido

1. Segundo Inmon, o Data Warehouse é orientado por assunto, integrado, volátil e variante no tempo.

Errado. É não volátil: dados carregados não sofrem atualização transacional; são carregados e consultados (TINO).

2. Em um Data Lake, adota-se tipicamente schema-on-read, armazenando os dados em formato bruto.

Certo. O esquema é aplicado na leitura; schema-on-write é característica do DW.

3. No SCD tipo 3, preserva-se o histórico completo inserindo-se uma nova linha com nova chave substituta.

Errado. Isso é o tipo 2. O tipo 3 cria coluna para o valor anterior (histórico limitado).

4. Tabela com valores (10, NULL, 20, 30) na coluna v: COUNT(*), COUNT(v) e AVG(v) retornam, respectivamente:

4, 3 e 20. COUNT(*) conta linhas; COUNT(v) ignora NULL; AVG = 60/3 = 20 (NULL fora do numerador e do denominador).

5. A cláusula HAVING pode ser usada para filtrar linhas antes do agrupamento, substituindo o WHERE com melhor desempenho.

Errado. HAVING filtra grupos, após o GROUP BY. Filtro de linhas é no WHERE (e filtrar cedo costuma ser mais eficiente).

6. No Apache Spark, transformações como filter e select são avaliadas de forma preguiçosa e só executadas quando uma ação, como count, é chamada.

Certo. Lazy evaluation: o Spark monta o DAG e otimiza antes de executar na ação.

7. Na abordagem ELT, os dados são transformados em um servidor intermediário antes de serem carregados no destino.

Errado. Isso descreve ETL. No ELT carrega-se primeiro e transforma-se dentro do destino (DW/Lakehouse).

8. Selecionar no cubo apenas o ano de 2025, mantendo as demais dimensões, é uma operação de:

Slice. Fixar um valor de uma única dimensão. Filtros em várias dimensões = dice.

9. Pelo teorema CAP, havendo partição de rede, um sistema distribuído deve optar entre consistência e disponibilidade.

Certo. Como a tolerância a partição é obrigatória em sistemas distribuídos, a escolha prática é CP ou AP.

10. Bancos NoSQL orientados a grafos são os mais indicados para cache de sessão com acesso por chave.

Errado. Cache/sessão é caso clássico de chave-valor (Redis). Grafo serve para relacionamentos (redes, fraude).

11. Em valores 100, 90, 90, 80 ordenados de forma decrescente, RANK() atribui ao valor 80 a posição 3.

Errado. RANK pula posições após empates: 1, 2, 2, 4. Quem dá 3 é o DENSE_RANK.

12. Uma tabela na 1FN com chave primária formada por uma única coluna pode apresentar dependência parcial, violando a 2FN.

Errado. Dependência parcial só existe quando a chave é composta por mais de um atributo.