Bancos colunares
Armazenamento orientado a colunas para escrita em volume e para consultas analíticas.
O problema: relatórios sobre muitas linhas
O painel de vendas pergunta "quanto vendemos por dia em março?". A tabela de eventos tem 20 milhões de linhas e cinco colunas, e a pergunta usa duas delas. Num banco relacional comum, as linhas ficam guardadas inteiras, uma depois da outra. Para somar uma coluna, o banco lê as páginas com as linhas completas, inclusive as colunas que a consulta não usa.
Um banco colunar guarda os valores de cada coluna juntos. Para somar valor, ele lê só o arquivo da coluna valor. E valores parecidos lado a lado se comprimem muito bem: uma coluna tipo com quatro valores possíveis vira quase nada.
Por linha (PostgreSQL): Por coluna (ClickHouse):
[ts, tipo, cliente, valor] ts: [t1, t2, t3, t4, ...]
[ts, tipo, cliente, valor] tipo: [compra, compra, compra, ...]
[ts, tipo, cliente, valor] cliente: [42, 7, 981, ...]
... valor: [19.90, 120.00, 5.50, ...]O nome "colunar" cobre duas famílias diferentes. Este tópico trata das duas, porque a confusão entre elas é comum.
| Família | Exemplos | Para quê |
|---|---|---|
| Colunar analítico | ClickHouse, DuckDB, BigQuery, Redshift, Snowflake | Consultas que agregam muitas linhas e poucas colunas |
| Linha larga (wide-column) | Cassandra, ScyllaDB, HBase, Bigtable | Escrita em volume distribuída em muitos servidores, leitura pela chave |
O colunar analítico, medido
Carregamos os mesmos 20 milhões de eventos (data e hora, tipo, cliente e valor) no PostgreSQL 18 e no ClickHouse 26, com 4 núcleos e 4 GB de memória para cada:
| PostgreSQL | ClickHouse | |
|---|---|---|
| Tempo de carga | 30 s | 5,9 s |
| Espaço em disco | 1.149 MB | 121 MB comprimidos (324 MB sem compressão) |
| Soma e contagem por tipo, sobre as 20 milhões de linhas | 1.476 ms | 128 ms |
| Compras por dia em março (sem índice no PostgreSQL) | 500 ms | 9 ms |
Compras por dia em março (com índice em tipo, ts no PostgreSQL) | 519 ms | 9 ms |
| Eventos de um cliente, sem índice | 292 ms | 6 ms |
| Eventos de um cliente, com índice no PostgreSQL | 0,35 ms | 6 ms |
Nas consultas analíticas, o ClickHouse foi de 11 a 55 vezes mais rápido e ocupou um décimo do espaço. O índice do PostgreSQL não ajudou nas compras por dia: elas tocam centenas de milhares de linhas, e o índice serve para achar poucas. Na última linha, a situação se inverte: para achar os 40 eventos de um cliente, o índice B-tree do PostgreSQL respondeu em 0,35 ms, e o ClickHouse precisou ler a coluna inteira de clientes.
Os números são de uma máquina de desenvolvimento, e servem para comparar os dois bancos entre si. As somas dos dois bancos conferiram.
O que o colunar faz mal
O mesmo desenho que acelera as leituras cobra nas escritas. O ClickHouse grava os dados em partes imutáveis, ordenadas e comprimidas, e as junta em segundo plano.
| Operação | Resultado |
|---|---|
1.000 INSERTs de uma linha cada | 69 s, 1.000 partes no disco |
1 INSERT com as mesmas 1.000 linhas | 60 ms, 1 parte |
Atualizar os 40 eventos de um cliente (ALTER TABLE ... UPDATE) | 1,1 s no ClickHouse, contra 2,5 ms no PostgreSQL |
Cada INSERT criou uma parte nova no disco, com seus arquivos e sua sincronização. Mil inserções de uma linha custaram mil vezes mais que uma de mil linhas, e deixariam o servidor ocupado juntando partes (no teste, a junção estava pausada para contar as partes). Uma aplicação que grava cada evento assim que ele acontece derruba o ClickHouse; o caminho é juntar os eventos em lotes, numa fila ou num buffer, e gravar de tempos em tempos.
A atualização reescreveu as partes que continham o cliente. Bancos analíticos são feitos para dados que chegam e ficam: eventos, medições, logs. Corrigir registros é possível, mas é exceção.
Linha larga: escrita distribuída, leitura pela chave
O Cassandra e o ScyllaDB guardam os dados em partições, distribuídas entre os servidores por uma chave. Dentro de cada partição, as linhas ficam ordenadas por uma chave de ordenação. A modelagem começa pela consulta: cada tabela é desenhada para uma pergunta.
CREATE TABLE leituras (
sensor_id int, dia date, ts timestamp, valor double,
PRIMARY KEY ((sensor_id, dia), ts) -- partição: sensor e dia; ordem: ts
) WITH CLUSTERING ORDER BY (ts DESC);Testamos no Cassandra 5:
| Consulta | Resultado |
|---|---|
WHERE sensor_id = 7 AND dia = '2026-11-15' LIMIT 2 | As duas leituras mais recentes, direto da partição |
WHERE valor > 21.6 | Recusada: Cannot execute this query as it might involve data filtering ... use ALLOW FILTERING |
WHERE sensor_id = 7 (sem o dia, que faz parte da partição) | Recusada pelo mesmo motivo |
O Cassandra só responde bem às consultas que dizem em qual partição procurar. Qualquer outra pergunta exige varrer todos os servidores, e ele a recusa por padrão. Para uma pergunta nova, cria-se uma tabela nova, com os mesmos dados organizados por outra chave.
O teste mostrou outra diferença importante. Um INSERT com uma chave que já existia sobrescreveu a leitura anterior (o valor passou de 21,5 para 99,9), sem erro nenhum: no Cassandra, inserir e atualizar são a mesma operação. Para impedir, há o IF NOT EXISTS, que no teste recusou o segundo cadastro com o mesmo e-mail, ao custo de uma rodada de consenso entre as réplicas.
Por que isso importa quando a IA escreve o código
Um assistente que integra um banco colunar costuma tratá-lo como um relacional:
- Inserções de uma linha por evento, em vez de lotes.
- Atualizações e exclusões frequentes, como num cadastro.
- Consultas por um registro só, que um índice B-tree resolveria melhor.
- No Cassandra, tabelas modeladas como no relacional, e
ALLOW FILTERINGpara fazer as consultas passarem. - Contar com o erro de chave duplicada no Cassandra, que não existe: o segundo
INSERTsobrescreve. - Relatórios pesados direto no banco transacional, sem resumo nem réplica.
O próximo nível compara quando usar cada família, como alimentar um banco analítico e como modelar no Cassandra.
Prompts para aprofundar
Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.
Bancos colunares em cinco minutos
Explique em no máximo cinco minutos de leitura o que é um banco colunar, para alguém que só usou bancos relacionais. Cubra só o essencial: guardar por linha e por coluna, por que agregações ficam muito mais rápidas, o que fica caro (gravar linha a linha, atualizar) e a diferença entre bancos analíticos e bancos de linha larga como o Cassandra. Use o exemplo de um painel de vendas sobre milhões de eventos. No final, me faça três perguntas curtas para eu verificar se entendi, e corrija as minhas respostas.
Por dentro de um banco analítico
Quero entender por que um banco analítico como o ClickHouse responde agregações tão rápido. Aja como um mentor e vá por etapas, esperando a minha resposta em cada uma: 1. Armazenamento por coluna e quanto se lê numa consulta que usa duas de dez colunas. 2. Compressão: por que colunas comprimem melhor que linhas, com exemplos. 3. Ordenação e o índice esparso do MergeTree. 4. Execução vetorizada e paralela. 5. Partes imutáveis e junções em segundo plano, e por que isso torna inserções pequenas e atualizações caras. Em cada etapa, me faça uma pergunta para verificar se entendi.
Linha larga não é colunar analítico
Quero entender os bancos de linha larga, como Cassandra e ScyllaDB, e por que eles não servem para relatórios. Explique: 1. Partições, chave de partição e chave de ordenação. 2. Por que só as consultas pela chave de partição são eficientes, e o que o ALLOW FILTERING faz. 3. Modelar uma tabela por consulta e duplicar os dados. 4. Por que INSERT e UPDATE são a mesma operação, e o custo do IF NOT EXISTS. 5. Consistência ajustável por consulta e réplicas em várias regiões. Depois me dê três consultas e peça que eu desenhe a tabela do Cassandra para cada uma.
Quando relatórios pedem outro banco
Quero entender quando os relatórios de um sistema justificam um banco analítico separado. Explique os sinais de que o banco transacional não dá mais conta dos relatórios, e compare as saídas: 1. Índices e tabelas de resumo. 2. Visões materializadas. 3. Réplica de leitura para relatórios. 4. DuckDB sobre arquivos exportados. 5. Um banco analítico alimentado continuamente. Depois me descreva três empresas com volumes diferentes e pergunte qual saída eu escolheria.