“Programming is the art of telling another human being what one wants the computer to do.”

Donald Knuth

18 - Banco de Dados

Bancos de dados estão no centro de praticamente todos os sistemas computacionais modernos. De aplicações bancárias e plataformas de comércio eletrônico a redes sociais, sistemas embarcados e ambientes científicos, a capacidade de armazenar, organizar, consultar e proteger dados é um requisito fundamental da computação. Por isso, o estudo de banco de dados envolve não apenas ferramentas e linguagens, mas também princípios de modelagem, integridade, concorrência, recuperação de falhas e escalabilidade.

Neste capítulo, serão apresentados os principais conceitos da área, começando pela noção de modelo de dados e pela etapa de projeto, passando pelos sistemas gerenciadores de bancos de dados, transações, linguagens de consulta e arquiteturas distribuídas, e chegando a temas analíticos, como mineração de dados. O objetivo é construir uma visão integrada, capaz de relacionar os fundamentos teóricos com as decisões práticas envolvidas no desenvolvimento e na operação de sistemas de informação.

18.1 - Modelo de Dados.

Em banco de dados, um dado é um valor bruto que representa alguma característica observável de uma entidade, evento ou processo. Quando esse valor é interpretado dentro de um contexto, ele passa a ter significado e pode ser tratado como informação. Por exemplo, o valor 2026-06-11 pode representar uma data; associado ao campo "data de matrícula", ele adquire um papel definido em um sistema.

Para que dados possam ser armazenados e manipulados com consistência, é necessário definir seus tipos e domínios. O tipo de dado estabelece a forma geral de representação, como inteiro, texto, data ou valor lógico. O domínio define o conjunto de valores válidos para um atributo, incluindo limites, formato e restrições. Assim, um atributo idade pode ser do tipo inteiro e ter como domínio valores entre 0 e 150, enquanto um atributo cpf pode exigir formato e unicidade específicos.

Um modelo de dados é uma representação abstrata da estrutura de uma base de dados. Ele descreve quais objetos do domínio precisam ser armazenados, quais características desses objetos são relevantes, como eles se relacionam entre si e quais restrições devem ser respeitadas. Os conceitos centrais nessa etapa são entidade, atributo, relacionamento e restrição.

  • Entidade: objeto ou conceito do domínio sobre o qual desejamos armazenar informações, como Aluno, Disciplina ou Professor.
  • Atributo: propriedade de uma entidade, como nome, matrícula, carga horária ou data de nascimento.
  • Relacionamento: associação entre entidades, como um aluno se matricular em uma disciplina.
  • Restrição: regra que limita valores ou relações válidas, como obrigatoriedade, unicidade ou integridade referencial.

Em termos mais formais, um modelo de dados não descreve apenas a estrutura dos dados, mas também sua semântica e as restrições que controlam seu uso. Isso significa que modelar dados não é apenas desenhar tabelas ou diagramas: é representar corretamente um recorte do mundo real, de forma que o sistema preserve significado e consistência ao longo do tempo.

Essa distinção é importante porque a mesma realidade pode ser representada de maneiras muito diferentes. Um sistema mal modelado pode até funcionar em cenários simples, mas tende a acumular redundâncias, ambiguidades e inconsistências quando cresce. Por isso, a qualidade do modelo influencia diretamente manutenção, desempenho, clareza das consultas e confiabilidade das informações produzidas.

Os modelos de dados podem ser discutidos em três níveis complementares:

  • Modelos conceituais
  • Modelos lógicos
  • Modelos físicos

O modelo conceitual descreve o domínio do problema em alto nível. Nele identificamos entidades, atributos e relacionamentos sem nos preocupar com detalhes do SGBD. Em um sistema acadêmico, por exemplo, podemos dizer que existem as entidades Aluno e Disciplina, relacionadas por Matrícula.

O modelo lógico refina essa descrição para uma abordagem específica de banco de dados, geralmente a relacional. Nesse nível, definimos tabelas, chaves primárias, chaves estrangeiras, cardinalidades e restrições. No mesmo exemplo, poderíamos ter as tabelas Aluno, Disciplina e Matricula, com referências entre elas.

O modelo físico descreve como a estrutura lógica será implementada em um SGBD particular. Aqui entram tipos concretos de dados, índices, particionamento, organização de páginas, métodos de acesso e outras decisões de armazenamento e desempenho.

Os três diagramas a seguir ilustram a progressão entre esses níveis usando o mesmo exemplo de domínio:

Diagrama conceitual com Aluno, Matricula e Disciplina.
Figura 1. Exemplo de modelo conceitual: foco nas entidades e no relacionamento principal.
Diagrama logico com tabelas Aluno, Matricula e Disciplina, incluindo chaves.
Figura 2. Exemplo de modelo lógico: surgem atributos, chaves e a entidade associativa que resolve o relacionamento muitos-para-muitos.
Diagrama fisico com tipos de dados, restricoes e indice.
Figura 3. Exemplo de modelo físico: aparecem tipos concretos, restrições e decisões de implementação.

Também é útil distinguir esquema e instância. O esquema descreve a estrutura relativamente estável da base de dados: nomes de tabelas, atributos, tipos, chaves e restrições. A instância é o conteúdo efetivo armazenado em um momento específico. Em outras palavras, o esquema é a definição; a instância é o conjunto de valores que preenche essa definição em determinado instante.

Essa separação ajuda a compreender a evolução de um sistema. O conteúdo da base muda continuamente com inserções, exclusões e atualizações, mas o esquema tende a mudar com menos frequência e de maneira mais controlada. Alterar o esquema é uma decisão de projeto; alterar a instância faz parte da operação normal do banco de dados.

Outro conceito central é a independência de dados. Deseja-se que mudanças no nível físico, como criação de índices ou reorganização de arquivos, causem o mínimo possível de impacto no nível lógico e nas aplicações. De modo semelhante, alterações lógicas controladas não deveriam exigir reescrita completa de todas as visões ou programas que consomem os dados. A separação entre níveis existe justamente para reduzir acoplamento e facilitar manutenção.

Na prática, essa ideia permite que um sistema cresça sem ser reconstruído a cada otimização. Pode-se, por exemplo, criar um índice para acelerar buscas por CPF sem mudar o conceito da entidade Pessoa no modelo lógico. Da mesma forma, uma aplicação pode consumir uma visão simplificada dos dados sem precisar conhecer detalhes de armazenamento interno.

Em bancos relacionais, uma base de dados é composta por várias tabelas, restrições e metadados. Uma tabela isolada pode ser usada como exemplo de relação, em que as colunas representam atributos e as linhas representam registros. Por exemplo:

Nome CPF Idade
João Ferreira 123.321.456-56 32
Maria Pereira 333.512.490-01 19

Na tabela acima, há dois registros e três atributos: Nome, CPF e Idade. Em um sistema real, essa tabela poderia fazer parte de um conjunto maior, com relações para endereços, matrículas, pagamentos ou departamentos, dependendo do domínio da aplicação.

A passagem do modelo conceitual para o lógico e, depois, para o físico é justamente o processo que transforma descrições do domínio em uma base de dados implementável. A próxima seção aprofunda esse processo sob a perspectiva de modelagem e projeto.

18.2 - Modelagem e Projeto de Banco de Dados.

Modelar um banco de dados significa transformar necessidades do mundo real em uma estrutura que possa ser implementada, consultada e mantida com segurança. Se na seção anterior vimos os níveis de abstração, aqui o foco é o processo de projeto: entender o domínio, escolher uma forma adequada de organizar os dados, reduzir redundâncias e decidir como a base será preparada para uso eficiente.

Uma analogia útil é pensar no projeto de banco como o projeto de um edifício. Primeiro entendemos o que o espaço precisa comportar, depois desenhamos a planta, em seguida definimos como os ambientes se conectam e, por fim, escolhemos materiais e acabamentos. Em banco de dados, esse percurso corresponde a requisitos, modelo conceitual, modelo lógico, normalização e implementação física.

Fluxo com as etapas requisitos, modelo conceitual, modelo lógico, normalização e modelo físico.
Figura 4. Fluxo simplificado de modelagem e projeto de banco de dados.

Suponha, por exemplo, um sistema acadêmico. Na etapa de requisitos, precisamos responder perguntas como: quais informações sobre alunos e disciplinas serão armazenadas, como registrar matrículas, quem poderá consultar os dados e quais relatórios serão necessários. Essas respostas orientam todas as decisões posteriores.

Depois do levantamento de requisitos, os dados podem ser organizados de maneiras diferentes, dependendo de sua natureza e do tipo de consulta esperado. Em termos gerais, eles costumam ser classificados em três grandes grupos:

Dados estruturados: seguem um esquema rígido, normalmente com linhas e colunas bem definidas. São típicos de bancos relacionais. No sistema acadêmico, tabelas como Aluno, Disciplina e Matricula são exemplos claros.

Dados semi-estruturados: têm organização parcial, mas não obedecem necessariamente a um esquema fixo. Formatos como JSON e XML são comuns. Um exemplo seria armazenar preferências de notificação dos alunos em um documento JSON, já que diferentes usuários podem ter opções distintas.

Dados não estruturados: não possuem organização tabular estável. Áudios, vídeos, imagens e textos livres entram nessa categoria. Em uma universidade, gravações de aula, PDFs de trabalhos e mensagens de fórum são exemplos desse tipo.

Escolher uma modelagem adequada depende, portanto, do tipo de dado e do tipo de pergunta que o sistema precisa responder. Nem todo problema pede uma base relacional, e nem toda flexibilidade é desejável. Em muitos casos, a melhor solução é aquela que facilita manutenção, integridade e compreensão do domínio ao longo do tempo.

Entre os modelos mais conhecidos de organização de bancos de dados estão:

  • Hierárquico
  • Grafo
  • Relacional
  • Orientado a objetos
  • Dimensional
  • Em rede
  • Documentos

O modelo hierárquico utiliza uma estrutura semelhante a uma árvore, com relações do tipo pai-filho. É adequado quando a navegação é predominantemente vertical. Um exemplo clássico é o registro do Windows.

O modelo de grafos representa entidades como nós e relacionamentos como arestas. Ele é útil quando o mais importante não é a lista de atributos, mas a malha de conexões. Uma boa analogia é um mapa de metrô: o valor está em saber como os pontos se ligam. Esse modelo aparece em redes sociais, recomendação e rotas. Exemplos: Neo4j e Amazon Neptune.

O modelo relacional organiza os dados em tabelas relacionadas por chaves. É o mais comum em sistemas transacionais porque oferece boa base formal, integridade e flexibilidade de consulta. No sistema acadêmico, ele se ajusta naturalmente a entidades como aluno, professor, disciplina e matrícula. Exemplos: MySQL, SQL Server e PostgreSQL.

Em bancos orientados a objetos, os dados são persistidos de forma próxima às estruturas da aplicação, preservando identidade e relacionamentos entre objetos. Eles são menos frequentes na prática cotidiana, mas podem fazer sentido em cenários específicos. Exemplos: ObjectDB e db4o.

A modelagem dimensional é comum em data warehouses e sistemas analíticos. Ela organiza fatos e dimensões para facilitar somas, médias, filtros históricos e análises OLAP. Em vez de pensar em operações do dia a dia, ela pensa em perguntas como “quantas matrículas ocorreram por semestre, curso e campus?”.

O modelo de documentos trabalha bem com dados semi-estruturados, normalmente em JSON, BSON ou XML, permitindo esquemas mais flexíveis. É apropriado quando registros do mesmo conjunto podem ter formatos ligeiramente diferentes. Exemplos: MongoDB e CouchDB.

Uma forma simples de resumir a escolha é a seguinte: o relacional é forte quando regras e consistência importam muito; o modelo de documentos favorece flexibilidade; o de grafos é ideal quando as conexões dominam o problema; e o dimensional é voltado a análise agregada.

Em projetos relacionais, uma etapa essencial é a normalização. Ela busca organizar os dados de forma a reduzir redundância e evitar anomalias de inserção, remoção e atualização. Uma analogia útil é a organização de uma despensa: se o mesmo item é guardado em vários lugares diferentes, qualquer mudança exige revisão repetida e aumenta a chance de erro.

Considere uma tabela única como Pedido(pedido_id, data, cliente_nome, cliente_telefone, produto_nome, produto_preco, quantidade). À primeira vista, ela parece prática. No entanto, o telefone do cliente e o preço do produto se repetem em várias linhas. Se o telefone mudar, todas as ocorrências precisam ser atualizadas. Se o último pedido de um cliente for apagado, talvez percamos também seus dados de contato. Essas são anomalias clássicas.

Exemplo visual de normalização, saindo de uma tabela unica para Cliente, Pedido, Produto e ItemPedido.
Figura 5. Exemplo de decomposição de uma tabela redundante em tabelas relacionadas.

Ao decompor essa estrutura em tabelas como Cliente, Pedido, Produto e ItemPedido, cada informação passa a ficar armazenada em um lugar mais apropriado. A 1FN exige valores atômicos e ausência de grupos repetidos; a 2FN elimina dependências parciais em chaves compostas; a 3FN reduz dependências transitivas. Para um texto introdutório, o ponto mais importante é entender o objetivo: cada tabela deve representar uma ideia principal, sem carregar atributos que pertencem a outra.

Depois de definir a estrutura lógica e normalizar a base, surgem decisões físicas voltadas a desempenho. A mais comum é a criação de índices. Um índice pode ser comparado ao índice remissivo de um livro: sem ele, precisamos percorrer página por página; com ele, chegamos muito mais rapidamente ao assunto desejado.

Se uma consulta busca repetidamente alunos por CPF, um índice sobre esse campo pode reduzir o custo de busca. Se a aplicação filtra matrículas por aluno_id e data_matricula, um índice composto pode ser apropriado. Isso não significa que toda coluna deva ser indexada: índices ocupam espaço e também têm custo de manutenção em inserções e atualizações.

Entre as estruturas frequentemente usadas para apoiar indexação e acesso estão:

  • Árvores B ou B+: muito usadas em índices por manterem a estrutura balanceada e funcionarem bem em buscas por faixa, ordenação e acesso a grandes volumes de dados em disco.
  • Tabelas hash: muito eficientes quando o padrão dominante é busca por igualdade exata, como procurar um registro por identificador.
  • Buckets: compartimentos usados em técnicas baseadas em dispersão para agrupar entradas associadas a um mesmo valor hash.
  • Listas invertidas: úteis para indexação textual, associando termos aos documentos ou registros em que aparecem.

Em resumo, modelar e projetar um banco de dados envolve mais do que escolher um SGBD. É preciso entender o domínio, selecionar uma forma adequada de organização, evitar redundância desnecessária e tomar decisões de desempenho compatíveis com o uso esperado. A seção seguinte entra justamente no papel do SGBD como software responsável por operar, proteger e administrar essa estrutura.

18.3 - Sistemas de Gerenciamento de Bancos de Dados (SGBD): Arquitetura, Segurança, Integridade.

Um Sistema de Gerenciamento de Banco de Dados, ou SGBD, é o software que organiza a vida interna de uma base de dados. Ele atua como intermediário entre aplicações, usuários e armazenamento persistente, recebendo comandos em alto nível e convertendo esses pedidos em operações controladas sobre páginas de dados, índices, logs e estruturas auxiliares. Em vez de cada programa abrir arquivos por conta própria, descobrir onde cada registro está gravado e tentar manter consistência manualmente, o SGBD centraliza essa responsabilidade e oferece uma interface estável para consulta, inserção, atualização, exclusão, controle de acesso, auditoria, backup e administração.

Essa mediação não é um detalhe de implementação: ela é o que torna viável o uso de dados em sistemas reais. Uma aplicação bancária, um ambiente de comércio eletrônico, um sistema hospitalar ou um portal acadêmico não lidam apenas com armazenamento; eles precisam garantir que milhares de operações sejam executadas sem corromper informações, sem violar permissões e sem perder coerência lógica. O SGBD existe justamente para transformar um conjunto de arquivos em uma infraestrutura confiável de dados.

Uma analogia útil é pensar no SGBD como a administração de uma grande biblioteca técnica. O usuário pede um livro pelo título; a administração sabe onde ele está, em qual setor, sob quais regras de consulta, quem pode retirá-lo, como registrar o empréstimo e como evitar extravios. Da mesma forma, quando uma aplicação solicita um dado, o SGBD cuida do caminho entre a solicitação lógica e o acesso físico ao armazenamento, além de aplicar regras de segurança e integridade durante todo o processo.

Do ponto de vista arquitetural, o SGBD fica entre o usuário ou a aplicação e os arquivos persistentes. Essa posição intermediária permite separar dois mundos: de um lado, o mundo lógico, em que falamos de tabelas, registros, consultas, visões e regras de negócio; de outro, o mundo físico, em que o sistema precisa lidar com blocos de disco, páginas, índices, caches, logs e estratégias de escrita. Essa separação reduz acoplamento e permite que a aplicação evolua sem precisar conhecer detalhes de organização interna dos dados.

Arquitetura simplificada com cliente, SGBD e armazenamento persistente.
Figura 6. O SGBD atua como camada intermediária entre aplicações e armazenamento persistente.

Internamente, um SGBD costuma ser organizado em componentes especializados. Embora os nomes exatos variem entre produtos, a ideia geral é bastante estável. Há um módulo de processamento de consultas, responsável por interpretar comandos como SELECT, INSERT, UPDATE e DELETE; um otimizador, que avalia formas alternativas de executar a consulta; um executor, que percorre tabelas e índices; um gerenciador de buffers, que decide quais páginas permanecem em memória; um gerenciador de armazenamento, que coordena arquivos, páginas e estruturas físicas; e um catálogo de metadados, que guarda definições de tabelas, colunas, índices, visões, permissões e estatísticas.

Esse arranjo ajuda a entender por que um SGBD faz muito mais do que “guardar tabelas”. Quando uma aplicação envia uma consulta, o sistema primeiro valida sua sintaxe e seu significado, verifica se as tabelas e colunas existem, checa permissões, consulta estatísticas para estimar custos, escolhe um plano de execução e só então inicia o acesso às estruturas físicas. O resultado que chega ao usuário parece simples, mas por trás dele há uma cadeia de decisões técnicas voltadas a corretude e desempenho.

Componentes internos de um SGBD, como processador de consultas, otimizador, gerenciador de buffers e armazenamento.
Figura 7. Visão simplificada dos principais componentes internos de um SGBD.

Outra distinção importante é entre contextos operacionais diferentes. Em muitos ambientes, o mesmo conceito de banco de dados aparece com finalidades distintas:

  • OLTP (Online Transaction Processing): voltado a operações frequentes, pequenas e transacionais, como cadastrar alunos, lançar matrículas e atualizar pagamentos.
  • OLAP (Online Analytical Processing): voltado a agregação, exploração e análise histórica, como comparar evasão por semestre, curso e campus.

Uma forma simples de memorizar a diferença é associar OLTP à pergunta “o que está acontecendo agora?” e OLAP à pergunta “o que aprendemos ao observar o histórico?”. Um sistema acadêmico usa OLTP quando registra uma nova matrícula, altera a situação de uma disciplina ou atualiza um pagamento. Já usa OLAP quando a coordenação cruza dados de vários semestres para descobrir padrões de evasão, sazonalidade de demanda ou desempenho por curso, campus e período.

Em ambientes reais, o acesso ao SGBD costuma ocorrer por rede, protocolo e autenticação. A aplicação se conecta a uma instância, envia comandos geralmente escritos em SQL e recebe de volta resultados ou confirmações de execução. No entanto, o que parece uma simples troca de mensagens envolve várias camadas: identificação do usuário, abertura de sessão, validação de permissões, escolha de plano de execução, uso de memória intermediária, leitura de páginas e eventual persistência de alterações. Uma mesma instância pode hospedar várias bases ou vários esquemas, cada um com regras próprias de administração, segurança, backup e uso de recursos.

Integridade e Consistência

Integridade, em banco de dados, significa manter os dados corretos segundo as regras do domínio representado. Não basta armazenar valores; é necessário garantir que esses valores façam sentido em conjunto. Se um sistema acadêmico exige que toda matrícula pertença a um aluno existente e a uma disciplina cadastrada, então o banco não deve aceitar registros órfãos, identificadores inexistentes ou combinações inválidas. A integridade protege o significado dos dados, não apenas sua presença física em disco.

Consistência, por sua vez, refere-se à passagem do banco de dados entre estados válidos. A ideia central é que, depois de uma operação completa e aceita pelo sistema, a base continue obedecendo às restrições definidas. Em um texto introdutório, é útil separar os dois conceitos: integridade está ligada ao conjunto de regras que descrevem o que é válido; consistência está ligada à preservação desse conjunto de regras ao longo das operações executadas pelo SGBD.

Na prática, o SGBD aplica integridade por meio de mecanismos declarativos e estruturais. Entre os mais importantes estão:

  • Chave primária: identifica unicamente cada registro de uma tabela.
  • Chave estrangeira: estabelece referências válidas entre tabelas.
  • Restrições NOT NULL: impedem ausência de valor em campos obrigatórios.
  • Restrições UNIQUE: evitam duplicidade indevida em atributos que devem ser exclusivos.
  • Restrições CHECK: limitam valores a condições lógicas previamente definidas.
  • Domínios e tipos: garantem que cada atributo receba valores compatíveis com sua natureza.

Esses mecanismos são fundamentais porque retiram da aplicação a responsabilidade exclusiva de validar tudo. Mesmo que um programa apresente falha, o próprio banco continua atuando como barreira de proteção. Se uma tabela de Matricula define uma chave estrangeira para Aluno, por exemplo, o SGBD recusa automaticamente a inserção de uma matrícula cujo aluno não exista. Essa verificação centralizada reduz inconsistências e evita que regras importantes fiquem espalhadas por diferentes partes do sistema.

Também é importante notar que integridade não se limita ao modelo lógico. Ela depende de como o SGBD administra leitura, escrita e atualização internas. Para oferecer desempenho, o sistema mantém páginas de dados temporariamente em memória, usa buffers, reordena acessos e pode adiar gravações físicas. Isso significa que a corretude não pode depender apenas da ordem aparente dos comandos do usuário; ela precisa ser sustentada por mecanismos internos robustos, que preservem o banco mesmo sob carga intensa, falhas parciais e múltiplos acessos concorrentes.

Relação entre regras de integridade, controle de acesso e operações permitidas em um SGBD.
Figura 8. Integridade e segurança atuam juntas para impedir dados inválidos e acessos indevidos.
Acesso e Segurança

Segurança em SGBDs envolve autenticação, autorização, auditoria e, em muitos cenários, criptografia. A lógica fundamental é simples: nem todo usuário deve poder ler, alterar ou remover qualquer dado. Em uma universidade, por exemplo, um aluno pode consultar as próprias notas e matrícula, mas não deve alterar notas de outros alunos; um professor pode lançar avaliações das turmas sob sua responsabilidade, mas não necessariamente acessar dados financeiros completos; a secretaria pode manter cadastros acadêmicos, sem por isso receber acesso irrestrito a todos os módulos do sistema.

O primeiro passo da segurança é a autenticação, isto é, verificar quem está tentando se conectar. O segundo é a autorização, que determina o que esse usuário autenticado pode fazer. O terceiro é a auditoria, que registra ações relevantes para rastreabilidade, detecção de abuso e conformidade. Em ambientes mais exigentes, soma-se ainda a criptografia, tanto para proteger dados em trânsito quanto para reduzir exposição de dados em repouso.

Entre os modelos clássicos de controle de acesso, destacam-se o DAC e o MAC. Em muitos ambientes reais, especialmente corporativos, também é comum o uso de administração por papéis, conhecido como RBAC (Role-Based Access Control), no qual permissões são agrupadas por função organizacional.

DAC (Discretionary Access Control): nesse modelo, o proprietário de um recurso ou um administrador pode conceder e revogar permissões a outros usuários. É uma abordagem flexível e muito comum em sistemas relacionais. Em SQL, esse tipo de política aparece em comandos como GRANT e REVOKE. Se um professor recebe permissão de leitura sobre uma tabela ou visão específica, ele pode acessar esse recurso dentro dos limites definidos.

MAC (Mandatory Access Control): aqui o acesso depende de políticas rígidas e classificações de sensibilidade impostas pelo sistema. O usuário não decide livremente quem verá determinado conteúdo. Esse modelo é mais frequente em contextos governamentais, militares ou altamente regulados, nos quais segregação formal de informação e confidencialidade forte são requisitos centrais.

RBAC (Role-Based Access Control): em vez de administrar permissões individualmente para cada usuário, o sistema define papéis como aluno, professor, coordenador e secretaria, associando a cada papel um conjunto de privilégios. Depois, os usuários são vinculados aos papéis adequados. Essa estratégia reduz complexidade administrativa e facilita manutenção, porque alterações de responsabilidade costumam ser refletidas pela troca de papel, e não pela reconfiguração manual de dezenas de permissões isoladas.

Uma boa prática transversal a esses modelos é o princípio do menor privilégio: cada usuário ou processo deve receber apenas as permissões estritamente necessárias para cumprir sua função. Isso reduz superfície de ataque, limita o impacto de erros e ajuda a conter danos caso credenciais sejam comprometidas. Em termos práticos, é preferível expor uma visão restrita da tabela de notas a um perfil de consulta do que conceder acesso direto e amplo à tabela completa.

Além do controle de acesso tradicional, alguns SGBDs oferecem mecanismos mais refinados, como visões para esconder colunas sensíveis, filtragem por linha para limitar quais registros cada usuário pode enxergar, mascaramento de dados e auditoria detalhada de operações. Esses recursos não substituem um bom modelo de permissões, mas complementam a política de segurança quando o domínio exige granularidade maior.

Em resumo, o SGBD não é apenas um repositório de registros nem apenas uma linguagem de consulta. Ele é uma infraestrutura especializada que organiza o acesso aos dados, traduz operações lógicas em ações físicas, preserva regras de integridade e aplica políticas de segurança sobre uma base compartilhada. Quando esse trabalho é bem feito, aplicações e usuários passam a operar sobre dados confiáveis, coerentes e protegidos. A próxima seção aprofunda justamente o que acontece quando múltiplas transações tentam atuar sobre a mesma base ao mesmo tempo e como o SGBD administra concorrência, falhas e durabilidade.

18.4 - Concorrência, Recuperação após Falha, Gerenciamento de Transações.

Quando várias operações tentam acessar a mesma base de dados ao mesmo tempo, o problema deixa de ser apenas armazenar dados corretamente e passa a ser coordenar ações simultâneas sem perder consistência. Esse é o domínio das transações, da concorrência e da recuperação de falhas. Em um sistema real, usuários não trabalham em fila, esperando o término completo uns dos outros. Matrículas são lançadas enquanto relatórios são consultados, pagamentos são atualizados enquanto secretarias alteram cadastros, e tudo isso precisa ocorrer de forma previsível. O papel do SGBD é permitir essa simultaneidade sem transformar a base em um conjunto de leituras incoerentes, atualizações perdidas e estados inválidos.

Uma transação pode ser entendida como uma unidade lógica de trabalho que agrupa uma ou mais operações sobre dados e que deve ser tratada como um todo. Em vez de pensar cada leitura ou escrita isoladamente, o sistema passa a enxergar um conjunto de passos relacionados por um objetivo comum. Transferir saldo entre contas, efetivar uma matrícula, reservar um assento ou lançar um conjunto de notas são exemplos típicos de transações. Se apenas parte dessas operações for concluída, o resultado pode se tornar incorreto. Por isso, o SGBD precisa de regras claras para confirmar ou desfazer seus efeitos.

Os comandos fundamentais associados a uma transação são tradicionalmente BEGIN ou início implícito, COMMIT e ROLLBACK. O COMMIT confirma os efeitos da transação; o ROLLBACK desfaz as alterações necessárias quando ocorre erro, cancelamento ou violação de alguma regra. Em termos conceituais, o banco não deve ficar “pela metade”: ou a unidade lógica é concluída, ou seus efeitos relevantes são revertidos.

Esse comportamento é sintetizado pelas propriedades ACID, que aparecem com frequência em teoria e na prática de bancos de dados:

  • Atomicidade (A - Atomicity): a transação é tratada como unidade indivisível. Todas as suas operações relevantes são efetivadas juntas ou, em caso de falha, o sistema desfaz o necessário para evitar estado parcial.
  • Consistência (C - Consistency): a execução de uma transação deve levar o banco de um estado válido para outro estado válido, preservando restrições e regras de integridade.
  • Isolamento (I - Isolation): mesmo quando várias transações ocorrem em paralelo, cada uma deve se comportar, até certo ponto, como se estivesse executando sozinha.
  • Durabilidade (D - Durability): uma vez confirmado o commit, seus efeitos não devem ser perdidos, mesmo diante de falhas de energia, software ou hardware.

Essas propriedades não significam que toda execução concorrente seja simples ou gratuita. Na prática, há tensões permanentes entre desempenho, grau de isolamento e custo de recuperação. Quanto mais rigoroso for o controle para impedir anomalias, maior pode ser o impacto sobre paralelismo, latência e throughput. O trabalho do SGBD consiste em equilibrar essas exigências sem abrir mão da corretude essencial do sistema.

Em um modelo abstrato de transação, duas operações aparecem como núcleo conceitual:

  • READ_ITEM(X): leitura de um item de dado X do banco para memória de trabalho da transação.
  • WRITE_ITEM(X): escrita de um novo valor de volta ao item X no banco.

Essas operações parecem simples, mas a interlevação entre transações concorrentes pode gerar problemas sérios. Se duas transações leem o mesmo saldo e ambas o atualizam sem coordenação, uma atualização pode sobrescrever a outra. Se uma transação lê um dado modificado por outra ainda não confirmada, pode basear decisões em informação provisória. Se um conjunto de linhas satisfaz uma consulta em um instante e deixa de satisfazê-la poucos milissegundos depois por causa de inserções concorrentes, o leitor pode observar resultados não repetíveis. O estudo de concorrência existe justamente para formalizar e controlar esses riscos.

Duas transações concorrentes acessando os mesmos dados com coordenação do SGBD.
Figura 9. O SGBD coordena a interlevação de transações para evitar conflitos incorretos.
Escalonamentos e Serializabilidade

Para organizar a execução das transações, os SGBDs trabalham com o conceito de escalonamento. Um escalonamento é a sequência efetiva de operações produzida quando diferentes transações têm suas ações intercaladas no tempo. Em uma execução serial, uma transação termina antes de a próxima começar. Em uma execução não serial, as operações se misturam para aproveitar melhor os recursos do sistema e aumentar concorrência.

  • Escalonamento serial: as transações são executadas integralmente uma após a outra. É simples de raciocinar, mas reduz paralelismo.
  • Escalonamento não serial: as operações são intercaladas para ganhar eficiência, desde que o resultado continue equivalente a uma execução correta.

O objetivo do controle de concorrência não é proibir interlevação, mas permitir interlevação segura. Dizemos que um escalonamento é serializável quando seu efeito final é equivalente ao de alguma execução serial das mesmas transações. Em outras palavras, embora as operações tenham sido misturadas, o resultado observado continua compatível com uma ordem correta de execução total. Esse conceito é central porque expressa a ideia de concorrência sem caos.

Há duas noções clássicas de serializabilidade: por conflito e por visão. Para fins introdutórios, a mais importante é a serializabilidade por conflito. Ela considera que duas operações entram em conflito quando pertencem a transações diferentes, acessam o mesmo item de dado e pelo menos uma delas é escrita. São os casos clássicos de leitura-escrita, escrita-leitura e escrita-escrita sobre o mesmo item. Se um escalonamento pode ser transformado em outro apenas trocando operações que não conflitam, ambos são equivalentes por conflito.

Uma forma tradicional de analisar isso é por meio do grafo de precedência. Nesse grafo, cada vértice representa uma transação e cada aresta direcionada indica que, por causa de um conflito, uma transação precisa preceder outra em qualquer ordem serial equivalente. Se o grafo for acíclico, o escalonamento é serializável por conflito. Se houver ciclo, existe dependência circular, o que impede equivalência a uma execução serial correta.

Esse raciocínio é valioso porque mostra que concorrência correta não é questão de “sorte” ou apenas de velocidade; ela depende de relações formais de dependência entre operações. O SGBD precisa observar essas dependências e impor coordenação suficiente para que leituras e escritas não produzam efeitos contraditórios.

Controle de Concorrência

As técnicas de controle de concorrência mais conhecidas utilizam bloqueios. Em linhas gerais, uma transação adquire permissão para ler ou escrever determinado item antes de acessá-lo, e essa permissão só pode coexistir com outras quando não houver conflito lógico.

  • Bloqueio compartilhado (shared lock): permite leitura concorrente por várias transações, desde que nenhuma esteja escrevendo o item.
  • Bloqueio exclusivo (exclusive lock): reserva o item para escrita, impedindo leituras ou escritas conflitantes enquanto o bloqueio estiver ativo.

Essa política evita anomalias importantes, mas também pode introduzir espera. Se duas transações precisarem de recursos diferentes em ordens incompatíveis, pode surgir um impasse, ou deadlock, em que cada uma espera indefinidamente por um recurso mantido pela outra. Nesses casos, o SGBD precisa detectar o ciclo de espera e escolher alguma transação como vítima para abortar e reiniciar depois. Por isso, concorrência segura não significa apenas “travar tudo”; significa coordenar conflitos com o menor custo possível.

Além dos bloqueios, muitos SGBDs modernos usam ou combinam técnicas baseadas em multiversão, como MVCC (Multi-Version Concurrency Control). Nessa abordagem, leituras podem enxergar versões consistentes anteriores dos dados, reduzindo contenção entre leitores e escritores. O benefício é aumentar paralelismo, especialmente em cargas com muitas consultas. O custo é a necessidade de gerenciar versões e definir com precisão quais modificações cada transação pode enxergar.

Na prática, o comportamento concorrente também depende do nível de isolamento escolhido. Quanto mais forte o isolamento, menos anomalias são permitidas; quanto mais fraco, maior tende a ser o espaço para desempenho e concorrência. Entre os fenômenos clássicos estudados, destacam-se:

  • Leitura suja (dirty read): uma transação lê alteração feita por outra que ainda não confirmou commit.
  • Leitura não repetível (non-repeatable read): a mesma consulta sobre a mesma linha retorna valores diferentes porque outra transação confirmou alteração no intervalo.
  • Leitura fantasma (phantom read): uma consulta por condição retorna conjuntos diferentes de linhas porque outra transação inseriu ou removeu registros que passaram a satisfazer a condição.

Por esse motivo, muitos SGBDs relacionais adotam como padrão níveis como READ COMMITTED ou REPEATABLE READ, e não necessariamente SERIALIZABLE. O nível mais forte oferece garantias mais rígidas, mas pode elevar contenção e reduzir throughput. A escolha do isolamento ideal depende do perfil da aplicação, do tipo de operação predominante e do custo aceitável de bloqueio ou reexecução.

Recuperabilidade e Rollback em Cascata

Além de controlar conflitos, o SGBD precisa garantir que a ordem de confirmações também faça sentido. Um escalonamento é dito recuperável quando, se uma transação Tj leu dados produzidos por outra transação Ti, então o commit de Ti ocorre antes do commit de Tj. Caso contrário, a segunda pode confirmar resultados baseados em dados que talvez ainda precisem ser desfeitos, o que compromete a confiabilidade do banco.

Quando essa disciplina não é respeitada, pode surgir o rollback em cascata. Imagine que uma transação T1 escreveu um valor ainda não confirmado, uma transação T2 leu esse valor e uma terceira transação T3 usou o resultado produzido por T2. Se T1 abortar, o sistema pode ser obrigado a abortar também T2 e T3, desencadeando uma cadeia de desfazimentos. Esse efeito é indesejável porque aumenta custo, reduz previsibilidade e amplia o impacto de uma falha localizada.

Por isso, muitos esquemas de controle de concorrência procuram produzir escalonamentos estritos ou ao menos cascadeless, nos quais transações não leem dados escritos por transações ainda não confirmadas. Essa restrição simplifica a recuperação e reduz o risco de propagar inconsistências temporárias.

Fluxo de recuperação de falhas com log, checkpoint, undo e redo.
Figura 10. A recuperação após falha usa logs e pontos de controle para refazer ou desfazer operações quando necessário.
Recuperação após Falha

Recuperação de falha é o conjunto de procedimentos usados para restaurar o banco de dados a um estado consistente depois de problemas como queda de energia, travamento do sistema, erro de software, interrupção do sistema operacional ou falha de hardware. O desafio não é apenas “voltar a funcionar”, mas voltar a funcionar sem perder corretude. Algumas alterações confirmadas precisam ser preservadas; outras, ainda incompletas, precisam ser desfeitas.

É nesse ponto que logs, checkpoints e políticas de atualização se tornam essenciais. Durante a execução normal, o SGBD registra informações suficientes para reconstruir o que aconteceu. Em caso de falha, ele consulta esse histórico para decidir quais operações devem ser refeitas e quais precisam ser desfeitas. Em sistemas grandes, essa etapa é indispensável porque o banco não pode depender apenas de backups completos, que são importantes para desastres maiores, mas lentos e imprecisos para restaurar o estado exato imediatamente anterior a uma interrupção operacional.

Entre as estratégias clássicas de atualização e recuperação, destacam-se:

  • Atualização adiada: as alterações só são propagadas para as páginas permanentes após o commit, o que reduz a necessidade de UNDO e enfatiza mecanismos de REDO.
  • Atualização imediata: alterações podem alcançar o armazenamento antes do commit, exigindo suporte coordenado tanto a UNDO quanto a REDO.
  • ARIES (Algorithms for Recovery and Isolation Exploiting Semantics): algoritmo clássico baseado em Write-Ahead Logging, repetição de histórico e registro explícito das ações de desfazimento. Sua recuperação é normalmente descrita em três fases: análise, REDO e UNDO.
  • Paginação de sombra: estratégia que mantém versões alternativas das páginas e troca a visão ativa da base após confirmação, reduzindo certos tipos de desfazimento, embora com custos e limitações próprios.

Também é útil distinguir os conceitos de UNDO e REDO. O UNDO desfaz efeitos de transações que não chegaram a se confirmar e, portanto, não devem permanecer na base. O REDO reaplica efeitos de transações já confirmadas, mas cujas alterações talvez ainda não tenham sido totalmente refletidas nas páginas persistidas no instante da falha. Essa dupla é fundamental para compatibilizar desempenho em tempo normal com robustez após interrupções.

Os checkpoints complementam essa lógica ao registrar pontos de controle periódicos. Em vez de reprocessar todo o histórico desde o início dos tempos, o SGBD passa a usar um marco mais recente para limitar o trabalho de recuperação. Isso reduz tempo de reinício e melhora previsibilidade operacional. Em sistemas de grande porte, esse detalhe faz diferença concreta porque o custo de recuperação também é um requisito de disponibilidade.

Em síntese, gerenciar transações, concorrência e recuperação significa controlar o ciclo completo da vida de uma operação no banco: seu início lógico, suas leituras e escritas, sua convivência com outras transações, sua confirmação e, se necessário, seu desfazimento ou reaplicação. Esse conjunto de mecanismos é o que permite ao SGBD suportar múltiplos usuários, alta taxa de operações e falhas inevitáveis sem perder a confiança sobre os dados armazenados.

18.5 - Linguagens de Consulta.

Linguagens de consulta são os meios formais pelos quais interagimos com uma base de dados. Elas permitem definir estruturas, inserir registros, recuperar informações, modificar conteúdos, estabelecer permissões e controlar transações. Em um primeiro olhar, pode parecer que consultar um banco se resume a escrever comandos para “buscar dados”, mas a realidade é mais ampla: uma linguagem de banco de dados também expressa o esquema da base, as restrições que ela deve obedecer e as operações administrativas necessárias para seu funcionamento seguro.

Nos SGBDs relacionais, a linguagem central é a SQL (Structured Query Language). Ela se tornou o padrão dominante porque consegue combinar, em uma mesma família de comandos, aspectos declarativos, administrativos e transacionais. A aplicação informa o que deseja obter ou alterar, e o SGBD decide como executar isso da maneira mais adequada. Cada produto concreto implementa dialetos e extensões próprias, como T-SQL no ecossistema Microsoft e PL/SQL na Oracle, mas a estrutura conceitual básica permanece amplamente reconhecível entre plataformas.

Essa característica declarativa é importante. Em muitas consultas SQL, o programador descreve o resultado desejado sem precisar especificar passo a passo como percorrer registros ou índices. Ao escrever um SELECT com filtros, junções e ordenações, por exemplo, o usuário define o objetivo da consulta; cabe ao otimizador do SGBD escolher um plano de execução eficiente. Essa separação entre intenção lógica e estratégia operacional é uma das grandes forças dos bancos relacionais.

Didaticamente, os comandos SQL costumam ser organizados em grupos funcionais. Essa divisão ajuda a entender que SQL não é apenas linguagem de busca, mas um conjunto de sublinguagens com finalidades complementares:

  • DDL (Data Definition Language): define e altera a estrutura do banco, com comandos como CREATE, ALTER e DROP.
  • DML (Data Manipulation Language): modifica os dados armazenados, com comandos como INSERT, UPDATE e DELETE.
  • DQL (Data Query Language): enfatiza a recuperação de dados, em especial por meio do comando SELECT.
  • DCL (Data Control Language): controla permissões e acesso, com comandos como GRANT e REVOKE.
  • TCL (Transaction Control Language): controla transações, com comandos como COMMIT, ROLLBACK e, em alguns sistemas, SAVEPOINT.
Categorias principais da linguagem SQL, incluindo DDL, DML, DQL, DCL e TCL.
Figura 11. A SQL reúne comandos de definição, manipulação, consulta, controle de acesso e controle transacional.

O grupo DDL lida com o desenho estrutural da base. Quando criamos uma tabela, definimos colunas, tipos, restrições, chaves e índices; quando a alteramos, estamos mexendo no esquema e, portanto, na própria forma como os dados serão organizados. Já o grupo DML atua sobre o conteúdo: inserir um novo aluno, atualizar a situação de uma matrícula ou excluir um cadastro incorreto são exemplos típicos de manipulação de dados. A DQL, por sua vez, concentra a formulação das consultas propriamente ditas, geralmente expressas por SELECT com cláusulas como FROM, WHERE, GROUP BY, HAVING e ORDER BY.

A DCL e a TCL completam o quadro ao trazer temas de administração e confiabilidade. A DCL permite expressar políticas de acesso diretamente na linguagem do banco, o que reforça a segurança do sistema. A TCL conecta a linguagem ao modelo transacional discutido na seção anterior, oferecendo comandos para confirmar ou desfazer unidades lógicas de trabalho. Desse modo, SQL não serve apenas para perguntar “quais dados existem?”, mas também para modelar, proteger e controlar o comportamento do banco.

Em termos de uso prático, uma consulta relacional frequentemente combina várias operações lógicas ao mesmo tempo. Pode-se selecionar linhas específicas, projetar apenas determinadas colunas, combinar tabelas por junção, agrupar resultados, aplicar funções de agregação e ordenar a saída final. A expressividade da SQL está justamente em permitir que essas etapas sejam descritas de forma relativamente compacta, ao mesmo tempo em que o SGBD mantém liberdade para otimizar a execução.

Embora a SQL seja dominante no mundo relacional, ela não esgota o universo das linguagens de banco de dados. Com o crescimento de sistemas distribuídos, aplicações web, dados semiestruturados e grandes volumes de informação heterogênea, surgiram abordagens conhecidas sob o rótulo amplo de NoSQL. Esse termo não significa simplesmente “sem SQL”, mas, de forma geral, identifica modelos que não se organizam prioritariamente em tabelas relacionais com esquema rígido e junções como mecanismo central de consulta.

Em sistemas NoSQL, a linguagem de acesso varia conforme o modelo de dados e o produto adotado. Em alguns casos, a consulta se parece com documentos JSON; em outros, com APIs de chave-valor; em outros ainda, com linguagens especializadas de navegação por grafos. O ponto central é que a linguagem acompanha a estrutura do dado. Isso altera a forma de pensar a modelagem, porque a consulta deixa de depender sempre do paradigma relacional clássico.

Há quatro famílias bastante conhecidas de bancos NoSQL:

  • Documento
  • Pares chave-valor
  • Colunas ou wide-column
  • Grafos
Quatro famílias de bancos NoSQL: documentos, chave-valor, colunas e grafos.
Figura 12. Em NoSQL, a linguagem de consulta tende a refletir diretamente o modelo de organização dos dados.

Nos bancos de documentos, cada registro é armazenado em estruturas como JSON, BSON ou XML. Esse formato favorece dados semiestruturados, com atributos que podem variar entre documentos, e reduz o atrito entre objetos usados pela aplicação e estruturas persistidas. As consultas frequentemente exploram campos internos do documento, filtros por atributos aninhados e índices criados sobre partes específicas da estrutura.

Nos bancos chave-valor, a ideia é ainda mais direta: cada chave identifica um valor associado. O modelo é simples, extremamente eficiente para acessos diretos e muito útil em caches, sessões, catálogos e metadados. A linguagem ou interface de consulta tende a ser minimalista, centrada em operações de leitura e escrita por chave. O ganho está na velocidade e na simplicidade; a limitação aparece quando se deseja realizar consultas complexas sobre o conteúdo armazenado.

Nos bancos orientados a colunas ou wide-column, os dados são organizados para favorecer distribuição, compressão e leitura eficiente de grandes conjuntos de atributos relacionados. Em muitos casos, o desenho da consulta é guiado pelos padrões de acesso esperados, e não apenas por princípios de normalização clássicos. Produtos como Cassandra e HBase se tornaram referências desse estilo, especialmente em cenários de alta escalabilidade e grandes volumes de escrita.

Nos bancos de grafo, a estrutura central não é a tabela nem o documento, mas a rede de nós e relacionamentos. Isso torna natural formular consultas sobre caminhos, vizinhanças, ciclos, centralidade e conexões entre entidades. Em aplicações como redes sociais, sistemas de recomendação, detecção de fraude e análise de dependências, esse modelo pode ser muito mais expressivo do que representar tudo por junções sucessivas em tabelas relacionais.

Essas diferenças mostram que linguagem de consulta e modelo de dados são conceitos inseparáveis. Quando mudamos a forma de representar a informação, mudamos também a forma de perguntar por ela. Por isso, compreender SQL e NoSQL não é apenas decorar comandos; é perceber como cada paradigma organiza o raciocínio sobre os dados.

Por trás dessas linguagens concretas existe ainda uma base teórica que dá sustentação ao modelo relacional. Dois pilares são especialmente importantes nesse contexto: a álgebra relacional e o cálculo relacional. Eles fornecem uma linguagem formal para descrever o comportamento das consultas e ajudam a explicar por que certas operações são corretas, equivalentes ou passíveis de otimização.

Álgebra Relacional

A álgebra relacional é um conjunto de operações aplicadas a uma ou mais relações, produzindo outra relação como resultado. Ela é tradicionalmente vista como uma linguagem procedural, no sentido de que descreve quais operações devem ser realizadas para chegar ao resultado desejado. Sua importância não está apenas no valor acadêmico: ela serve como referência conceitual para entender consultas SQL e para raciocinar sobre equivalência e otimização de expressões.

Entre as operações básicas mais conhecidas estão:

  • Seleção (σ): Filtra as linhas de uma relação que satisfazem uma condição especificada.
  • Projeção (π): Extrai colunas específicas de uma relação, removendo duplicatas.
  • União (∪): Combina as linhas de duas relações, removendo duplicatas.
  • Diferença (-): Retorna as linhas que estão em uma relação, mas não na outra.
  • Produto Cartesiano (×): Combina cada linha de uma relação com cada linha de outra.
  • Junção (⨝): Combina linhas de duas relações baseadas em uma condição de correspondência.

Essas operações podem ser encadeadas para construir consultas sofisticadas. Uma seleção pode reduzir o conjunto de linhas relevantes; uma projeção pode preservar apenas os atributos desejados; uma junção pode combinar informações espalhadas por tabelas distintas. Em termos intuitivos, a álgebra relacional descreve os blocos conceituais a partir dos quais consultas relacionais são montadas.

Cálculo Relacional

O cálculo relacional oferece uma perspectiva diferente. Em vez de descrever uma sequência de operações, ele especifica as propriedades que o resultado deve satisfazer. Por isso, é visto como uma abordagem não procedural ou declarativa. Essa lógica está mais próxima do espírito da SQL: o usuário descreve o que quer, e o sistema decide como obter.

Existem duas variantes principais:

  • Cálculo Relacional de Tuplas (TRC): usa variáveis que representam tuplas inteiras de uma relação e formula condições que essas tuplas devem satisfazer.
  • Cálculo Relacional de Domínio (DRC): usa variáveis associadas aos valores dos atributos, isto é, aos domínios das colunas.

Ambas as variantes expressam consultas de maneira declarativa, concentrando-se no “o quê” em vez do “como”. Isso é fundamental para a teoria relacional porque permite estudar correção, segurança e equivalência sem ficar preso a detalhes de implementação. Em um curso introdutório, o mais importante é perceber a relação entre esses formalismos e a prática: a álgebra ajuda a visualizar operações; o cálculo ajuda a pensar em especificação declarativa; a SQL, por sua vez, funciona como linguagem de uso efetivo inspirada por esses fundamentos.

Para tornar essa conexão mais concreta, suponha duas tabelas em um banco de dados relacional: Funcionarios e Departamentos.

  • Funcionarios tem as colunas FuncionarioID, Nome e DepartamentoID.
  • Departamentos tem as colunas DepartamentoID e NomeDepartamento.
Exemplo 1: Seleção e Junção

Para encontrar todos os funcionários que trabalham no departamento de TI, precisamos combinar as tabelas e filtrar o departamento desejado. Em álgebra relacional, isso pode ser expresso assim:

$$ \sigma_{\text{NomeDepartamento = 'TI'}} (\text{Funcionarios} \Join_{\text{Funcionarios.DepartamentoID = Departamentos.DepartamentoID}} \text{Departamentos}) $$ Exemplo 2: Junção

Para listar o nome de cada funcionário junto com o nome de seu departamento, usamos a operação de junção:

$$ \text{Funcionarios} \Join_{\text{Funcionarios.DepartamentoID = Departamentos.DepartamentoID}} \text{Departamentos} $$

O resultado é uma relação combinada em que cada funcionário aparece associado ao departamento correspondente. Em SQL, isso se traduziria naturalmente em um SELECT com JOIN, o que mostra como a prática cotidiana herda diretamente essas construções formais.

Para os mesmos exemplos, podemos observar como a ideia aparece em cálculo relacional.

Exemplo 1: Cálculo Relacional de Tuplas (TRC) para Seleção

Para encontrar funcionários do departamento de TI, uma formulação em TRC pode ser escrita da seguinte forma:

$$ \{ f \mid f \in \text{Funcionarios} \land \exists d \in \text{Departamentos} (d.\text{DepartamentoID} = f.\text{DepartamentoID} \land d.\text{NomeDepartamento} = \text{'TI'}) \} $$

Essa expressão seleciona as tuplas f de Funcionarios para as quais existe uma tupla d em Departamentos com o mesmo identificador de departamento e com nome igual a TI.

Exemplo 2: Cálculo Relacional de Domínio (DRC) para Junção

Para listar o nome de cada funcionário com o nome do seu departamento, uma expressão em DRC pode ser:

$$ \{ \langle n, nd \rangle \mid \exists i, did \, ( \langle i, n, did \rangle \in \text{Funcionarios} \land \exists d \, ( \langle did, nd \rangle \in \text{Departamentos} ) ) \} $$

O resultado são pares formados pelo nome do funcionário e pelo nome do departamento sempre que os identificadores de departamento coincidirem. Embora essas expressões pareçam mais abstratas do que uma consulta SQL cotidiana, elas mostram a base lógica do modelo relacional e ajudam a compreender por que operações como seleção, projeção e junção podem ser manipuladas, equivalidas e otimizadas formalmente.

Em síntese, estudar linguagens de consulta significa olhar para três níveis ao mesmo tempo. No nível prático, a SQL oferece a linguagem do dia a dia para modelar, consultar e administrar dados relacionais. No nível de diversidade arquitetural, os modelos NoSQL mostram que diferentes estruturas exigem diferentes formas de consulta. No nível teórico, álgebra e cálculo relacional explicam a lógica que sustenta o paradigma relacional. Juntos, esses três planos permitem entender não apenas como escrever consultas, mas também por que elas funcionam, como podem ser otimizadas e em quais contextos cada modelo se torna mais apropriado.

18.6 - Bancos de Dados Distribuídos.

Até aqui, o capítulo tratou principalmente do banco de dados como se ele estivesse disponível a partir de uma única instância lógica. Em muitos sistemas pequenos ou médios, essa simplificação é suficiente: uma aplicação conversa com um servidor de banco de dados centralizado, que concentra armazenamento, processamento de consultas, controle de concorrência e persistência. No entanto, à medida que o volume de dados cresce, o número de usuários aumenta, a necessidade de disponibilidade se torna mais rígida e os sistemas passam a operar em diferentes máquinas, regiões ou datacenters, a arquitetura puramente centralizada começa a se tornar limitada.

É nesse contexto que entram os bancos de dados distribuídos. Em vez de armazenar toda a base em um único nó físico, o sistema passa a organizar dados e processamento sobre vários computadores interconectados por rede. Para o usuário ou para a aplicação, idealmente o banco continua parecendo uma unidade coerente; internamente, porém, ele precisa coordenar servidores diferentes, cópias de dados, partições, protocolos de comunicação e políticas de consistência. Essa mudança traz ganhos importantes de escalabilidade e tolerância a falhas, mas também introduz novos desafios conceituais e operacionais.

Antes de chegar ao cenário distribuído propriamente dito, vale observar a evolução arquitetural que costuma ocorrer em sistemas de informação. A configuração mais simples é aquela em que aplicação e armazenamento residem no mesmo ambiente computacional. Em sistemas embarcados, protótipos, ferramentas locais ou aplicações de baixa escala, essa proximidade reduz latência, simplifica configuração e elimina parte da complexidade de rede. Em contrapartida, limita a escalabilidade, concentra risco de falha em um único ponto e dificulta isolar responsabilidades.

No modelo de duas camadas, a aplicação e o banco ficam em máquinas distintas. Essa separação caracteriza o cliente-servidor clássico: o cliente envia requisições e o servidor de banco de dados responde, processando consultas e controlando o acesso aos dados. Já na arquitetura em três camadas, a apresentação, a lógica de negócio e os serviços de dados passam a ocupar camadas separadas. O cliente interage com um servidor de aplicação, que por sua vez se comunica com o banco. Esse desenho melhora segurança, organização e escalabilidade funcional, mas ainda pode depender de um único repositório central de dados.

O passo seguinte ocorre quando não basta apenas separar funções; torna-se necessário distribuir também os próprios dados. Isso pode acontecer por diferentes motivos: crescimento de volume, necessidade de atender usuários em várias regiões, exigência de alta disponibilidade, redução de gargalos de leitura e escrita, tolerância a falhas locais ou aproveitamento de clusters de máquinas comuns em vez de servidores únicos cada vez maiores. Em ambientes de Big Data e serviços globais, essa distribuição deixa de ser opção marginal e passa a ser parte central da arquitetura.

Arquitetura distribuída com aplicação, coordenador e vários nós de dados interconectados.
Figura 13. Em bancos distribuídos, dados e processamento são coordenados entre vários nós, mesmo que a aplicação enxergue um sistema lógico unificado.

De forma geral, um banco de dados distribuído é um sistema em que os dados são armazenados em múltiplos nós conectados por rede, mas administrados de maneira integrada. Esses nós podem estar no mesmo datacenter, em racks diferentes, em diferentes cidades ou até em regiões geográficas distantes. O grau de distribuição varia conforme o projeto, mas a ideia central permanece: os dados não estão todos no mesmo lugar, e o sistema precisa decidir onde armazenar, como acessar, como replicar, como sincronizar e como recuperar o estado correto diante de falhas.

Essa arquitetura pode assumir formas distintas. Em alguns casos, o dado é fragmentado, isto é, diferentes partes da base são armazenadas em nós diferentes. Em outros, o dado é replicado, de modo que múltiplas cópias da mesma informação existam em máquinas distintas. Muitas soluções combinam ambas as estratégias: fragmentam para escalar capacidade e replicam para aumentar disponibilidade e tolerância a falhas. Por isso, estudar bancos distribuídos exige separar claramente os conceitos de fragmentação, replicação, sincronização e coordenação.

Fragmentação e Distribuição dos Dados

Fragmentar um banco significa dividir seus dados em partes menores, chamadas fragmentos ou partições, e distribuí-las entre diferentes nós. Essa divisão pode seguir critérios variados. Uma tabela de clientes pode ser fragmentada por região geográfica; uma base de pedidos pode ser distribuída por intervalo de datas; um conjunto de usuários pode ser alocado por hash do identificador. O objetivo é repartir carga e armazenamento de forma que nenhuma máquina precise responder sozinha por toda a massa de dados.

Essa decisão afeta diretamente o desempenho das consultas. Quando a partição acompanha o padrão dominante de acesso, o sistema pode atender muitas operações localmente, com menor custo de comunicação. Quando a distribuição não acompanha esse padrão, consultas passam a depender de múltiplos nós ao mesmo tempo, elevando latência e complexidade. Em outras palavras, em ambientes distribuídos, modelagem física e padrão de consulta ficam ainda mais fortemente acoplados do que em bancos centralizados.

Além da fragmentação horizontal, em que subconjuntos de linhas são distribuídos entre nós, também se fala em fragmentação vertical, quando grupos de atributos de uma mesma relação são separados. A escolha entre esses formatos depende do domínio, do perfil de acesso e do custo de reconstruir a informação quando ela precisa ser consultada de forma integrada.

Replicação de Dados

Replicação é a técnica de manter cópias de dados em mais de um nó. Seu benefício mais evidente é a disponibilidade: se uma máquina falha, outra réplica pode continuar respondendo. A replicação também pode melhorar desempenho de leitura, distribuindo consultas entre diferentes servidores, e reduzir o impacto de interrupções localizadas em datacenters ou segmentos da rede. No entanto, ela introduz o problema delicado de manter múltiplas cópias coerentes ao longo do tempo.

Em termos gerais, há duas abordagens bastante conhecidas:

  • Replicação síncrona: a atualização só é considerada concluída depois que as réplicas necessárias confirmam a operação. Essa estratégia fortalece a consistência, mas aumenta latência e sensibilidade a atrasos de rede.
  • Replicação assíncrona: a atualização é confirmada em um nó principal ou em um subconjunto inicial, e propagada depois para outras réplicas. Isso melhora desempenho e disponibilidade imediata, mas abre janelas temporárias de divergência entre cópias.

Em alguns sistemas, também aparecem estratégias híbridas, nas quais certas réplicas participam do caminho crítico da confirmação e outras são atualizadas posteriormente. A escolha depende do que o sistema prioriza: baixa latência, alta disponibilidade, consistência forte ou tolerância a partições de rede.

Replicação entre nó primário e réplicas, com comparação entre replicação síncrona e assíncrona.
Figura 14. Replicação melhora disponibilidade, mas exige políticas explícitas de propagação e consistência entre cópias.
Consistência e Sincronização

Quando existem múltiplas cópias ou múltiplas partições sendo atualizadas em tempos diferentes, o banco distribuído precisa de mecanismos de sincronização. O problema central deixa de ser apenas “como armazenar” e passa a incluir “como ordenar eventos” e “como decidir qual versão do dado é a válida”. Em um sistema concentrado em um único nó, a ordem relativa das operações é mais fácil de observar; em um ambiente distribuído, atrasos de rede, relógios não perfeitamente alinhados e falhas parciais tornam essa tarefa muito mais complexa.

Por isso, bancos distribuídos usam algoritmos e metadados para coordenar atualizações. Entre os conceitos clássicos aparecem carimbos de tempo, relógios lógicos, relógios vetoriais, logs de replicação e protocolos de quorum. A função desses mecanismos é permitir que o sistema detecte conflitos, imponha uma ordem aceitável entre eventos ou ao menos reconheça quando duas versões divergiram e precisam de reconciliação.

Nem todo sistema distribuído persegue o mesmo tipo de consistência. Alguns priorizam consistência forte, buscando garantir que todos os clientes vejam uma visão uniforme do dado logo após a confirmação da operação relevante. Outros adotam consistência eventual, aceitando que cópias diferentes possam divergir por algum tempo, desde que convirjam depois. Essa escolha não é apenas técnica; ela depende do domínio da aplicação. Em um sistema bancário, certas divergências temporárias podem ser inaceitáveis. Em um catálogo global de produtos ou em um feed de conteúdo, pequenas defasagens podem ser toleráveis em troca de disponibilidade e desempenho.

Comunicação e Coordenação entre Nós

Em um banco distribuído, a rede deixa de ser mero meio de transporte e passa a ser parte constitutiva do sistema. Os nós precisam trocar mensagens para encaminhar consultas, replicar atualizações, eleger líderes, detectar falhas, sincronizar estados e confirmar decisões coordenadas. Protocolos de comunicação gerais, como TCP/IP, fornecem a base da conectividade, mas o comportamento distribuído do banco depende de protocolos de nível mais alto, específicos para replicação, consenso, descoberta de membros ou recuperação.

Esse ponto é importante porque muitos problemas de bancos distribuídos não decorrem de erro de modelagem, mas da própria natureza das falhas em rede. Diferentemente de um sistema puramente local, aqui podem ocorrer particionamentos, atrasos arbitrários, mensagens duplicadas, perda temporária de conectividade e visões diferentes do estado global entre os nós. Em consequência, o sistema precisa ser projetado para operar corretamente mesmo quando partes dele continuam funcionando e outras ficam temporariamente isoladas.

Consultas e Transações Distribuídas

Quando uma consulta envolve dados espalhados em vários nós, o banco precisa decidir onde executar cada parte do trabalho, como combinar resultados intermediários e como minimizar custo de comunicação. Uma consulta distribuída pode exigir filtragem local em cada nó, envio parcial de resultados, junções remotas ou agregações coordenadas. Esse tipo de processamento é mais caro do que consultar um único repositório local, razão pela qual o desenho da distribuição influencia fortemente o desempenho global.

As transações distribuídas elevam ainda mais o nível de complexidade. Em vez de confirmar alterações dentro de um único gerenciador local, o sistema precisa coordenar múltiplos participantes para garantir que todos apliquem a operação de forma compatível. Protocolos como Two-Phase Commit (2PC) são usados para isso em muitos cenários: primeiro, o coordenador pergunta aos participantes se eles estão prontos para confirmar; depois, se todos concordarem, envia a ordem final de commit. Essa solução melhora consistência entre nós, mas tem custo de coordenação, bloqueio e sensibilidade a falhas do coordenador.

Em alguns ambientes, também se fala em infraestrutura XA (eXtended Architecture) para integrar transações que atravessam múltiplos gerenciadores de recursos. O ponto conceitual importante é que transações distribuídas buscam preservar atomicidade entre partes fisicamente separadas do sistema, o que é muito mais difícil do que garantir atomicidade dentro de um único nó.

Em síntese, bancos de dados distribuídos existem para atender demandas que ultrapassam os limites de um único servidor: maior escala, maior disponibilidade, maior proximidade geográfica dos dados e maior resiliência operacional. Em troca, exigem decisões cuidadosas sobre fragmentação, replicação, consistência, sincronização e coordenação transacional. O ganho não é “gratuito”: a distribuição resolve certos gargalos ao preço de introduzir novas formas de complexidade. Compreender esse trade-off é essencial para avaliar quando um sistema distribuído é realmente necessário e como projetá-lo de forma coerente.

18.7 - Mineração de Dados.

Mineração de dados, ou Data Mining, é o processo de descobrir padrões, regularidades, correlações e estruturas relevantes em grandes conjuntos de dados. Mais do que simplesmente consultar registros já conhecidos, a mineração busca extrair conhecimento novo ou pouco evidente, transformando dados brutos em indícios úteis para análise, previsão e tomada de decisão. Por isso, ela ocupa uma posição intermediária entre banco de dados, estatística e aprendizado de máquina: depende de armazenamento e organização adequados, mas também de técnicas analíticas capazes de reconhecer relações significativas.

Em muitos contextos, o desafio não está apenas no volume absoluto dos dados, mas na dificuldade de interpretá-los manualmente. Uma base acadêmica pode conter milhares de matrículas, notas, evasões, históricos e perfis de curso; uma plataforma digital pode registrar milhões de cliques, compras, avaliações e trajetórias de navegação. Nesses cenários, a mineração de dados procura responder perguntas como: há grupos naturais de comportamento? Quais atributos ajudam a prever determinado resultado? Que eventos costumam ocorrer juntos? Existem tendências temporais ou relações estruturais relevantes entre entidades?

De forma ampla, as tarefas de mineração podem ser organizadas em alguns grandes grupos:

  • Agrupamento ou clusterização
  • Testes de hipótese e análise estatística
  • Regras de associação
  • Classificação e árvores de decisão
  • Mineração em grafos
  • Redes neurais e outros modelos preditivos
  • Análise de séries temporais
Principais tarefas de mineração de dados, como clusterização, associação, classificação, grafos e séries temporais.
Figura 15. A mineração de dados reúne diferentes famílias de técnicas para descobrir padrões em bases extensas.
Agrupamento e Segmentação

O agrupamento, também chamado de clusterização, busca particionar os dados em grupos cujos elementos sejam internamente semelhantes e externamente distintos. É uma técnica clássica de aprendizado não supervisionado, pois o algoritmo não recebe previamente a classe correta de cada exemplo; ele tenta descobrir estruturas latentes a partir das próprias características observadas. Em um contexto universitário, por exemplo, pode-se identificar perfis de alunos com padrões semelhantes de desempenho, frequência ou trajetória curricular, mesmo sem rótulos prévios definidos por um especialista.

Essa técnica é útil não apenas para segmentação, mas também como etapa intermediária em processos analíticos maiores. Clusters podem servir de resumo exploratório dos dados, apoiar compressão, redução de dimensionalidade, filtragem de ruído e formulação de hipóteses posteriores. Em termos intuitivos, clusterizar é tentar responder à pergunta: “quais subconjuntos parecem naturalmente pertencer ao mesmo grupo?”

Hipóteses e Relações Estatísticas

Outra vertente importante é a avaliação estatística de relações entre variáveis. Testes de hipótese ajudam a verificar se um padrão observado pode ser explicado apenas por acaso ou se há evidência suficiente para tratá-lo como relevante. Nesse contexto, distingue-se a hipótese nula, que normalmente representa ausência de efeito ou ausência de relação, da hipótese alternativa, que sugere a existência de algum comportamento significativo.

Esse tipo de análise é essencial para evitar conclusões precipitadas. Dizer que duas variáveis apresentam correlação não significa automaticamente que uma causa a outra. Em mineração de dados, esse cuidado é particularmente importante porque grandes bases podem exibir muitas associações espúrias. Quanto maior o número de atributos observados, maior o risco de encontrar relações aparentemente interessantes que não se sustentam fora da amostra analisada.

Regras de Associação

As regras de associação procuram identificar eventos que tendem a ocorrer juntos. Em vez de prever um valor numérico ou atribuir uma classe, elas descrevem padrões do tipo “quando A ocorre, B também costuma ocorrer”. Esse tipo de descoberta ficou clássico em cenários de análise de cestas de compra, mas seu uso vai muito além do varejo. Pode-se buscar associações entre disciplinas cursadas, evasão e desempenho, entre tipos de acesso a serviços digitais ou entre categorias de eventos em logs operacionais.

Para avaliar a qualidade de uma regra de associação, dois parâmetros aparecem com frequência:

  • Suporte: mede a frequência com que o padrão aparece no conjunto total de transações ou registros.
  • Confiança: mede quão forte é a associação, isto é, com que frequência a ocorrência do antecedente é acompanhada pela ocorrência do consequente.

Algoritmos como o Apriori são clássicos nesse domínio porque exploram sistematicamente combinações frequentes de itens e constroem regras a partir delas. O ponto central é que a mineração de associação não prova causalidade; ela revela regularidades observadas, que depois precisam ser interpretadas à luz do contexto.

Classificação e Árvores de Decisão

Na classificação, o objetivo é atribuir um objeto a uma classe previamente definida com base em seus atributos. Diferentemente da clusterização, aqui o modelo é treinado com exemplos rotulados. Isso significa que existe uma fase de aprendizado supervisionado, na qual o sistema observa casos anteriores para aprender padrões discriminantes. Em um sistema educacional, por exemplo, pode-se tentar classificar estudantes em categorias de risco de evasão com base em frequência, notas, histórico de reprovação e perfil socioeconômico.

Árvores de decisão são especialmente úteis nesse contexto porque produzem representações interpretáveis. Em vez de gerar apenas uma pontuação abstrata, elas descrevem sequências de decisões baseadas em atributos, facilitando a explicação do modelo para analistas humanos. Outros classificadores, como redes neurais, podem oferecer maior poder preditivo em alguns cenários, mas costumam ser menos transparentes na interpretação direta de suas decisões.

Grafos e Estruturas Relacionais Complexas

Nem todo padrão relevante está nos atributos isolados de cada registro. Em muitos problemas, a estrutura das conexões entre entidades é o dado mais importante. É aí que entra a mineração em grafos. Quando trabalhamos com redes sociais, cadeias de dependência, fluxos de navegação, relações acadêmicas ou padrões de fraude, pode ser mais adequado representar o domínio como nós e arestas do que como linhas independentes de uma tabela.

Nesse tipo de mineração, procuram-se comunidades, centralidades, caminhos frequentes, subgrafos recorrentes e estruturas anômalas. O foco deixa de ser apenas “quais valores aparecem” e passa a ser também “como as entidades se conectam”.

Séries Temporais e Tendências

Séries temporais analisam o comportamento de uma variável ao longo do tempo. O objetivo é identificar tendências, sazonalidades, dependências temporais e padrões úteis para previsão. Em bases acadêmicas, por exemplo, é possível observar evolução de evasão por semestre, demanda por disciplinas em diferentes períodos ou mudanças no desempenho médio ao longo dos anos.

Entre as características frequentemente discutidas nesse contexto estão:

  • Estacionariedade: situação em que propriedades estatísticas relevantes permanecem relativamente estáveis ao longo do tempo.
  • Sazonalidade: flutuações recorrentes associadas a períodos específicos.
  • Autocorrelação: dependência entre valores da série em instantes diferentes.

Modelos como ARIMA, VAR em cenários multivariados e Holt-Winters aparecem com frequência em análise e previsão temporal. A ideia comum entre eles é explorar regularidades na evolução da série para inferir comportamento futuro ou entender melhor sua dinâmica passada.

Avaliação e Validação

Independentemente da técnica escolhida, mineração de dados não se resume a “rodar um algoritmo”. É necessário definir o problema, preparar os dados, escolher critérios de avaliação e validar se os padrões encontrados realmente têm significado útil. Um fluxo simplificado de trabalho costuma envolver três passos principais:

  1. Geração do modelo ou do padrão candidato, com base nos dados disponíveis.
  2. Definição do critério de interesse, isto é, que tipo de regularidade ou capacidade preditiva se deseja encontrar.
  3. Validação dos resultados, verificando se o padrão é estável, interpretável e suficientemente confiável para uso prático.

Essa etapa final é decisiva. Um padrão estatisticamente detectável pode não ser útil; um modelo altamente preciso em treinamento pode falhar em dados novos; uma regra frequente pode ser trivial ou irrelevante do ponto de vista do domínio. Por isso, mineração de dados exige sempre diálogo entre técnica e interpretação. O valor não está apenas em encontrar estruturas matemáticas, mas em descobrir conhecimento que faça sentido no contexto em que os dados foram produzidos.


Glossário

ACID
Conjunto de propriedades transacionais formado por atomicidade, consistência, isolamento e durabilidade.
Atributo
Propriedade associada a uma entidade ou relação, como nome, matrícula ou data de nascimento.
Banco de dados relacional
Banco de dados que organiza as informações em relações, usualmente representadas por tabelas interligadas por chaves.
Checkpoint
Ponto de controle registrado pelo SGBD para reduzir o trabalho necessário em processos de recuperação após falha.
Clusterização
Técnica de mineração de dados que agrupa elementos semelhantes sem depender de classes previamente rotuladas.
Cardinalidade
Restrição que expressa quantas ocorrências de uma entidade podem se associar a ocorrências de outra.
Chave estrangeira
Atributo ou conjunto de atributos que referencia a chave primária de outra tabela.
Chave primária
Atributo ou conjunto de atributos que identifica unicamente cada registro de uma tabela.
Consistência eventual
Modelo em sistemas distribuídos no qual réplicas podem divergir temporariamente, mas tendem a convergir com o tempo.
Dado
Valor bruto que representa alguma característica observável de uma entidade, evento ou processo.
Deadlock
Impasse em que duas ou mais transações ficam esperando indefinidamente por recursos mantidos umas pelas outras.
Domínio
Conjunto de valores válidos que um atributo pode assumir.
Entidade
Objeto, conceito ou elemento do domínio sobre o qual se deseja armazenar informações.
Esquema
Descrição estrutural da base de dados, incluindo tabelas, atributos, tipos, chaves e restrições.
Escalonamento
Sequência efetiva de operações de uma ou mais transações, possivelmente intercaladas no tempo.
Fragmentação
Divisão da base de dados em partes menores, distribuídas entre diferentes nós em um sistema distribuído.
Informação
Dado interpretado em contexto, dotado de significado para análise ou tomada de decisão.
Instância
Conteúdo efetivo da base de dados em um momento específico do tempo.
Isolamento
Propriedade transacional que controla como transações concorrentes podem observar os efeitos umas das outras.
Integridade referencial
Regra que assegura a consistência entre valores de chaves relacionadas em tabelas diferentes.
Metadado
Dado sobre dado, usado para descrever estrutura, significado e organização das informações armazenadas.
MVCC
Multi-Version Concurrency Control, técnica que mantém múltiplas versões de dados para reduzir contenção entre leituras e escritas.
Modelo conceitual
Representação de alto nível do domínio, focada em entidades, relacionamentos e regras de negócio.
Modelo de dados
Conjunto de conceitos usados para descrever dados, relacionamentos, semântica e restrições de uma base.
Modelo físico
Representação voltada à implementação em um SGBD específico, com detalhes de armazenamento e acesso.
Modelo lógico
Representação intermediária que organiza as estruturas do banco em um modelo específico, como o relacional.
OLAP
Online Analytical Processing, abordagem voltada à análise histórica, agregação e exploração de dados.
OLTP
Online Transaction Processing, abordagem voltada a operações frequentes, pequenas e transacionais do dia a dia.
Quorum
Critério de coordenação em sistemas distribuídos em que um número mínimo de nós precisa participar para validar certa operação.
Registro
Ocorrência individual de uma relação, geralmente representada por uma linha em uma tabela.
Relacionamento
Associação entre entidades do domínio, como aluno cursar disciplina ou cliente realizar pedido.
Replicação
Manutenção de cópias de dados em múltiplos nós para aumentar disponibilidade, tolerância a falhas ou capacidade de leitura.
Restrição
Regra que limita valores, associações ou operações válidas em uma base de dados.
Rollback
Operação que desfaz os efeitos de uma transação não confirmada ou encerrada com erro.
SGBD
Sistema de Gerenciamento de Banco de Dados, software responsável por armazenar, consultar, proteger e administrar a base.
Serializabilidade
Propriedade de um escalonamento concorrente cujo efeito final é equivalente ao de alguma execução serial correta.
Série temporal
Sequência de observações ordenadas no tempo, analisada para identificar tendência, sazonalidade e dependências temporais.
SQL
Structured Query Language, linguagem padrão usada para definir, consultar, manipular e administrar dados em SGBDs relacionais.
Tupla
Termo formal do modelo relacional para um registro de uma relação.
WAL
Write-Ahead Logging, princípio segundo o qual alterações devem ser registradas em log persistente antes de atingir definitivamente as páginas de dados.