Prévia do material em texto
Código Logístico 59714 BANCO DE DADOS II Paulo Sérgio Cougo Fundação Biblioteca Nacional ISBN 978-85-387-6717-6 9 7 8 8 5 3 8 7 6 7 1 7 6 Banco de Dados II Paulo Sérgio Cougo IESDE BRASIL 2021 Todos os direitos reservados. IESDE BRASIL S/A. Al. Dr. Carlos de Carvalho, 1.482. CEP: 80730-200 Batel – Curitiba – PR 0800 708 88 88 – www.iesde.com.br © 2021 – IESDE BRASIL S/A. É proibida a reprodução, mesmo parcial, por qualquer processo, sem autorização por escrito do autor e do detentor dos direitos autorais. Projeto de capa: IESDE BRASIL S/A. Imagem da capa: DrHitch/Shutterstock CIP-BRASIL. CATALOGAÇÃO NA PUBLICAÇÃO SINDICATO NACIONAL DOS EDITORES DE LIVROS, RJ C892b Cougo, Paulo Sérgio Banco de dados II / Paulo Sérgio Cougo. - 1. ed. - Curitiba [PR] : Iesde, 2021. 114 p. : il. Inclui bibliografia ISBN 978-85-387-6717-6 1. Banco de dados. 2. Banco de dados - Gerência. 3. Sistemas de recu- peração da informação. 4. Estruturas de dados (Computação). 5. Organiza- ção de arquivos - Computação. I. Título. 21-68695 CDD: 005.7 CDU: 004.658 Paulo Sérgio Cougo Pós-graduado em Análise de Sistemas na Administração de Empresas pela Pontifícia Universidade Católica do Paraná (PUCPR). Tecnólogo em Processamento de Dados pela Universidade Federal do Paraná (UFPR). Profissional com atuação nas funções de administrador de banco de dados e administrador de dados. Responsável pela modelagem e pelo projeto e monitoramento de bancos de dados corporativos. Instrutor de cursos de modelagem de banco de dados e professor em curso de pós-graduação em banco de dados. Autor e revisor de livros sobre modelagem e projeto de banco de dados. Agora é possível acessar os vídeos do livro por meio de QR codes (códigos de barras) presentes no início de cada seção de capítulo. Acesse os vídeos automaticamente, direcionando a câmera fotográ�ca de seu smartphone ou tablet para o QR code. Em alguns dispositivos é necessário ter instalado um leitor de QR code, que pode ser adquirido gratuitamente em lojas de aplicativos. Vídeos em QR code! SUMÁRIO 1 Armazenamento e estruturas de dados 9 1.1 Armazenamento em disco 10 1.2 Organização de arquivos 17 1.3 Técnicas de hashing 21 1.4 Estrutura de indexação de arquivos 24 2 Processamento e otimização de consultas 31 2.1 Medidas de avaliação de custo de consultas 31 2.2 Avaliação de expressões 39 2.3 Algoritmos para processamento e otimização 47 3 Gerenciamento de transações 54 3.1 Conceitos de transações 55 3.2 Propriedades de uma transação 59 3.3 Suporte a transações no SQL 66 3.4 Técnicas de controle de concorrência 69 4 Técnicas de recuperação em banco de dados 75 4.1 Classificação das falhas 76 4.2 Estruturas de recuperação 80 4.3 Técnicas de recuperação 85 5 Data warehousing e data mining 93 5.1 Conceitos 94 5.2 Arquitetura 102 5.3 Aplicabilidade 106 Gabarito 110 Agora é possível acessar os vídeos do livro por meio de QR codes (códigos de barras) presentes no início de cada seção de capítulo. Acesse os vídeos automaticamente, direcionando a câmera fotográ�ca de seu smartphone ou tablet para o QR code. Em alguns dispositivos é necessário ter instalado um leitor de QR code, que pode ser adquirido gratuitamente em lojas de aplicativos. Vídeos em QR code! A utilização de estruturas de banco de dados para dar suporte aos sistemas de informação já é comum entre projetistas de grande parte dos sistemas corporativos, departamentais e até pessoais. Apesar de os sistemas gerenciadores de bancos de dados (SGBD) simplificarem excessivamente as tarefas de manipulação dos dados, ainda podemos considerar como essencial conhecer quais são esses tratamentos e processos executados automaticamente pelos SGBD. Com o intuito de melhor organizar o conhecimento das técnicas utilizadas por um SGBD e compreender a importância de se tomar alguns cuidados durante o projeto e a construção dos nossos bancos de dados, organizamos este livro em cinco capítulos. No Capítulo 1 veremos quais são as estruturas físicas utilizadas por um sistema gerenciador de banco de dados para armazenar e recuperar os dados. Reconheceremos as estruturas de organização de arquivos utilizadas na criação de um banco para recuperação de dados por meio de índices, mediante a utilização de técnicas de hashing e indexação. Já no Capítulo 2, tendo compreendido como os dados são organizados e mantidos, trataremos das técnicas de otimização de consultas utilizadas pelos sistemas gerenciadores de bancos de dados, de modo a permitir que os comandos SQL possam ter sua estrutura declarativa transformada em uma estrutura procedimental otimizada. No Capítulo 3 apresentaremos as técnicas de gerenciamento de transações concorrentes, permitindo que vários processos possam consultar e atualizar simultaneamente o mesmo conjunto de dados. Conheceremos quais são as características de uma transação e como elas asseguram a manutenção da integridade de um banco de dados. Também entenderemos como o SQL permite que o controle de concorrência seja executado com sucesso. Chegando ao Capítulo 4, abordaremos os tipos de falha que podem ocorrer e os recursos de recuperação de falhas que um SGBD pode prover, bem como as estruturas de dados APRESENTAÇÃOVídeo 8 Banco de Dados II complementares que o sistema cria para permitir que as integridades lógica e física de um banco de dados sejam asseguradas. Já no Capítulo 5, após conhecermos todas as técnicas e as estruturas utilizadas pelos SGBD para assegurar a integridade de um banco de dados transacional, estudaremos as estruturas de dados, o processo de modelagem e a criação de data warehouses e data smarts focados em sistemas de apoio à decisão. Veremos também as diferenças de abordagem entre os sistemas transacionais (OLTP) e de apoio à decisão (OLAP). Com todo esse conteúdo, participaremos de uma jornada que apresentará desde os primeiros conceitos, passando por métodos e técnicas para gerenciamento seguro de dados, chegando até estruturas não convencionais orientadas a sistemas de apoio à decisão. Esperamos que você tenha uma gratificante experiência. Bons estudos! Armazenamento e estruturas de dados 9 1 Armazenamento e estruturas de dados Todos os aspectos envolvidos na modelagem conceitual, lógica e física de um banco de dados requerem que estruturas físicas de armazenamento sejam utilizadas para materializar e tornar fisicamente acessíveis os dados do banco projetado e criado. As melhores práticas utilizadas para o projeto irão requerer também tecnologias equivalentes para produzir os resultados de desempenho, segurança, acessibilidade e compartilhamen- tos desejados. De pouco adiantaria ter planejado um banco de dados com altos requisitos de compartilhamento e desempe- nho, se pelo lado da oferta tecnológica não houver meios para liberar esses resultados aos usuários. A oferta de diferenciais tecnológicos por diferentes fabri- cantes, tanto de software como de hardware, acaba, por fim, por determinar o alcance ou não dos resultados esperados pelas áreas de negócio das corporações que dependem dos bancos de dados para o sucesso de suas operações. Neste capítulo veremos os conceitos e estruturas físicas utilizadas para o armazenamento e acesso aos dados físicos nos bancos de dados. Por meio desta abordagem poderemos reconhecer as estruturas físicas de armazenamento de dados em disco, os modelos de organização de arquivos, as alternati- vas para construção de índices de acesso, bem como ver como estas impactam as estruturas de bancos de dados em sua cria- ção e manipulação. 10 Banco de Dados II 1.1 Armazenamento em disco Vídeo Desde os primórdios da informática, um desafio sempre fez parte do dia a dia dos profissionais desta área: como e onde armazenar os dados. Com a habilidade da informática de simular a capacidade hu- mana de interpretar, decidir, avaliar, transformar e produzirdados, o primeiro desafio do armazenamento de dados, que era o próprio pro- cessamento dos dados, deixava de ser o foco. Mesmo os computado- res mais rudimentares, por meio de um modelo de máquinas baseado em processamento sequencial de comandos, tinham então a capaci- dade de processar dados, oferecendo um processamento com maior velocidade, para volumes maiores e com menores taxas de erro. O de- safio de reproduzir a capacidade de processamento humano havia sido superado pelas máquinas. Mas e o que dizer sobre a capacidade de reter grandes volumes de dados para servirem de entrada para estes programas e de reter os dados produzidos como saídas por estes programas? Um novo desafio então surgiu e, com o passar do tempo, várias alternativas foram cria- das. O armazenamento de dados passou então por várias gerações, desde os cartões perfurados, as fitas perfuradas, as fitas magnéticas, os discos magnéticos, chegando hoje até os discos de estado sólido, cada um com suas características, benefícios e desvantagens. Hoje, quando falamos em armazenamento físico de dados, seja ele de uma simples mensagem, de um documento, de uma agenda, ou até de um banco de dados corporativo, várias opções surgem como alternativas. Do pequeno ao grande dispositivo, do pequeno ao grande banco de dados, quase tudo pode ser armazenado em vários tipos de dispositivos. Imagine hoje quantos gigabytes um simples telefone celu- lar é capaz de armazenar – sejam eles sob a forma de agendas, bancos de dados de contatos, banco de dados de imagens etc. Dentre os dispositivos de armazenamento mais comumente encon- trados nos dispositivos eletrônicos baseados em microprocessadores, podemos ter: • Memória Cache Este tipo de memória é aquela utilizada para o armazenamento de dados perenes ou temporários; é um dos componentes básicos asso- Armazenamento e estruturas de dados 11 ciados ao próprio processador. Essa é a forma mais rápida de memória para acesso de dados, porém é também a mais cara. Ela é normalmen- te limitada e pequena (um processador Intel 7, por exemplo, pode ter até o máximo de 12 megabytes de cache) e não é um tema de preocu- pação quanto se fala de um banco de dados. Não é, portanto, usada por um software gerenciador de banco de dados para a manipulação dos dados. • Memória principal (ou memória RAM, Random Access Memory) A memória RAM é uma que já pode ter maior capacidade de arma- zenamento – da ordem dos gigabytes, podendo chegar a terabytes –, mas ainda não é usada como fonte de armazenamento perene de da- dos, devido ao fato de depender de energização para retenção de seus dados. Caso ocorra a interrupção do fornecimento de energia, essa memória deixará de reter os dados nela carregados. Ela tem um papel importante no cenário dos gerenciadores de banco de dados, pois será utilizada como meio de aceleração para acesso aos dados usados mais frequentemente. Ou seja, aquela porção do banco de dados acessada com maior frequência será carregada na memória RAM, pois o acesso dela é muito mais rápido. • Memória flash Esta memória difere da memória principal tradicional, pois os dados armazenados numa memória flash não são perdidos em caso de in- terrupção do fornecimento de energia. Podemos então utilizá-las para armazenamento perene de dados. Essas são as memórias utilizadas mais recentemente para dar origem aos discos de estado sólido, que na verdade não são discos, mas sim bancos de memória, compostos por vários chips de memória flash. É uma tecnologia promissora que promete substituir os discos magnéticos. • Discos magnéticos Estes têm sido ao longo de décadas o meio mais efetivo para o ar- mazenamento de grandes volumes de dados. Há décadas os discos magnéticos de uso corporativo não chegavam a armazenar sequer 512 megabytes. Hoje, facilmente você irá encontrar um notebook para uso pessoal com um disco magnético de mais de 1 terabyte. Os sistemas gerenciadores de banco de dados se baseiam predominantemente nesse tipo de armazenamento. No vídeo Como funciona a memória cache?, publicado pelo canal The Hardware Show, você verá a arquitetura básica de um processa- dor e como a memória cache se insere neste contexto. Uma aborda- gem bastante didática e esclarecedora poderá lhe trazer informações, como os benefícios e restrições que a memória cache apresenta para a otimização de tempo de processamento das ins- truções e para o tempo de acesso a dados. Disponível em: https:// www.youtube.com/ watch?v=uS3XnXgr1DE. Acesso em: 24 nov. 2020. Vídeo https://www.youtube.com/watch?v=uS3XnXgr1DE https://www.youtube.com/watch?v=uS3XnXgr1DE https://www.youtube.com/watch?v=uS3XnXgr1DE 12 Banco de Dados II • Discos de estado sólido (Solid State Drive – SSD) A tecnologia de discos magnéticos evoluiu incrivelmente nos últi- mos anos, produzindo discos fisicamente menores, mas com capaci- dades de armazenamento enormes. Com a capacidade que possui, um disco que hoje está dentro de um notebook, décadas atrás ocuparia uma sala com uma área de mais de 10m², exigindo toda uma estrutura de ar condicionado, piso falso (para manutenção) etc. Porém, o fato de serem menores e terem maior capacidade não foi suficiente. Os discos de antigamente esbarraram no limite de tempo demandado para me- canicamente acessarem os dados que estavam gravados em suas su- perfícies, isto é, tornaram-se lentos se comparados aos acessos feitos eletronicamente em memória RAM, e este tempo não poderia mais ser baixado. Surge então a ideia de agrupar vários chips de memória flash para criar discos de estado sólidos. Teríamos alta capacidade de arma- zenamento, pequeno espaço físico e ausência de movimentos mecâni- cos, ou seja, alta velocidade de acesso. • Discos óticos Com o objetivo de superar os limites mecânicos e físicos do arma- zenamento dos discos magnéticos, um novo método de armazena- mento e leitura de dados foi desenvolvido. O Compact Disc Read-Only Memory, mais conhecido como CD-Rom, utiliza-se de tecnologia laser para leitura e gravação de dados em formato ótico. Eles apresentam limitações para regravação de dados e, também, um pior tempo de acesso se comparado aos discos de estado sólido, contudo transfor- maram-se por muito tempo em excelentes alternativas para backup de dados. • Armazenamento em fita magnética Quando falamos em fitas magnéticas podemos nos lembrar daque- las velhas fitas usadas para guardar tanto os primeiros arquivos se- quenciais, usados nos antigos sistemas das décadas de 1970, 1980 e 1990. Porém, não são essas as fitas utilizadas atualmente. Hoje temos cartuchos lacrados em que a fita se enrola e desenrola dentro de um mesmo cartucho, não sendo transferida de um rolo A para um rolo B, como antigamente. Segundo Elmasri e Navathe (2006), o acesso aos blocos de dados na ordem sequencial é a principal característica de uma fita. Esse aces- so se dá quando o cabeçote de leitura/escrita percorre um bloco no No texto Como funcionam os discos rígidos (ART943), o autor Newton Braga mostra em detalhes a tecnologia de gravação e leitura em discos magné- ticos, tanto do ponto de vista mecânico (como o acesso é feito) quanto do ponto de vista eletrônico (como saber o que está gravado no disco). É uma oportunidade de compreender como algo tão complexo pode ter se transformado em algo tão amplamente utilizado no mercado. Disponível em: https://www. newtoncbraga.com.br/index.php/ como-funciona/7727-como- funcionam-os-discos-rigidos- art943. Acesso em: 24 nov. 2020. Leitura https://www.newtoncbraga.com.br/index.php/como-funciona/7727-como-funcionam-os-discos-rigidos-art943 https://www.newtoncbraga.com.br/index.php/como-funciona/7727-como-funcionam-os-discos-rigidos-art943 https://www.newtoncbraga.com.br/index.php/como-funciona/7727-como-funcionam-os-discos-rigidos-art943 https://www.newtoncbraga.com.br/index.php/como-funciona/7727-como-funcionam-os-discos-rigidos-art943 https://www.newtoncbraga.com.br/index.php/como-funciona/7727-como-funcionam-os-discos-rigidos-art943Armazenamento e estruturas de dados 13 meio de um cartucho até chegar ao bloco requisitado. Por essa razão o acesso à fita pode ser lento e as fitas podem não ser utilizadas para armazenar dados on-line, exceto para aplicações específicas. Entretan- to, elas atendem a uma função muito importante: o backup do banco de dados. • Estrutura de disco Sendo os discos magnéticos as principais mídias de armazena- mento de grandes volumes de dados, é importante que se conheçam alguns dos elementos e das características que os compõem. Conhe- cendo estas estruturas poderemos entender quais são os pontos que merecem atenção, até mesmo durante o projeto relacional e o projeto físico. Poderemos entender, por exemplo, por que o acesso a duas ta- belas distintas para obter um conjunto de dados pode ser mais lento do que acessar uma única tabela. Figura 1 Estrutura física de um disco magnético Trilha/Cilindro trilha 1 trilha 10 setor 1 setor 20 Cabeçotes 8 Cabeçotes Pratos Fonte: Canal Tech, 2021. O primeiro ponto a ser observado é que existem diversos elemen- tos mecânicos envolvidos no acesso a um disco (braços, cabeçotes, eixo etc). Esses elementos mecânicos precisam ter acesso a todas as trilhas e setores de um disco. Olhando a Figura 1, podemos imaginar que se um dado X se encontra gravado no setor 1, mas um outro dado Y se 14 Banco de Dados II encontra gravado no setor 20, haverá um tempo gasto para que se es- pere o disco girar saindo do setor 1 e chegando até o setor 20, para então a leitura do dado Y ser feita. Se um dado X estiver gravado na trilha 1, mas um dado Y estiver gravado na trilha 10, teremos também que aguardar um deslocamento do braço do disco, para que ele saia da área mais externa do disco e se desloque para a área mais interna. Estes dois tempos, também chamados de latência, precisam ser consi- derados como um atraso na entrega dos dados que venhamos a solici- tar ao sistema de gerenciamento de banco de dados – SGBD. Na estrutura apresentada podemos observar a presença de setores, que são as menores unidades de leitura e gravação em disco, portanto, mesmo que você deseje somente uma porção dos dados que estão no setor 20, na trilha 1, acabará tendo que aguardar o mecanismo fa- zer a leitura de todo o setor 20, trazendo eventualmente dados que você nem desejava ter acesso naquele momento. Também o tempo de transferência de todos os dados, relevantes ou não do setor 20, devem ser computados como tempo adicional na entrega dos dados solicita- dos pelo SGBD ao sistema operacional. Do ponto de vista do SGBD, um outro elemento deve ser conhecido: o bloco ou página. Essa é a unidade que o SGBD utilizará como mínima porção para leitura ou gravação de dados. Mais à frente veremos deta- lhes sobre esta estrutura. Todos os dispositivos de armazenamento vistos operam de modo cooperado, cumprindo finalidades diferentes em função do aproveita- mento de suas características. Assim, por exemplo, a memória RAM, por ter uma velocidade de acesso maior, é usada para manter dados que precisam mais constantemente ser acessados. Já um disco magnético, por ter um tempo de acesso mais lento, é usado para manter dados que tenham menor frequência de acesso. Chamamos de armazenamento primário aquele que é operado e controlado diretamente pelo sistema operacional, tal como a memó- ria RAM e a memória cache. Já o armazenamento secundário é aquele que exige intermediação do armazenamento primário, tal como discos magnéticos, fitas magnéticas etc. Esta intermediação do armazenamento secundário feita pelo arma- zenamento primário potencializa os resultados e o desempenho das leituras e gravações de dados pelo SGBD e por outros programas que Armazenamento e estruturas de dados 15 exigem interação com dispositivos de entrada e saída de dados. Ve- remos as seguir como este processo acontece, segundo descrito por Elmasri e Navathe (2006). Como os dados de um banco de dados estarão sempre armazena- dos em um disco magnético, ao solicitar a leitura de um dado X, pode- ríamos imaginar que o sistema operacional pudesse ir sempre ao disco para procurar pelo bloco físico de dados (bloco 0001) onde se encontra o dado X e que trouxesse, então, X para ser processado pela memória RAM. Figura 2 Transferência de dados entre disco e memória sem buffer Memória RAM Disco MagnéticoX X Y Z A B Bloco 0001 Bloco 0002 Fonte: Elaborada pelo autor. Porém, caso esse processo fosse sempre executado, na próxima vez em que outro usuário solicitasse o acesso ao dado X (imaginando que ele é um dado frequentemente requisitado), o sistema operacional te- ria que novamente executar um acesso ao disco, com todo o consumo de tempo já apresentado anteriormente (esperar o deslocamento do braço de leitura até a trilha e o giro do disco até o setor necessário). Para agilizar esse processo, e imaginando que o dado X possa ser re- quisitado novamente no futuro, um recurso extra de memória cache é adicionado, conforme apresentado na Figura 3. Figura 3 Transferência de dados entre disco e memória com buffer BufferMemória RAM Disco MagnéticoX X Y Z X Y Z A B Bloco 0001 Bloco 0001 Bloco 0002 Fonte: Elaborada pelo autor. 16 Banco de Dados II Assim sendo, ao ser solicitado o dado X, primeiramente o siste- ma operacional irá verificar se ele já não se encontra na área de buffer (que tem um acesso muito rápido). Caso já esteja lá, não será necessário ir até o disco buscá-lo. Caso não esteja localizado no buffer, então ele será procurado no disco e o bloco ao qual ele pertence será carregado para o buffer, ficando disponível para uma próxima busca futura. Esse mesmo processo acontece também quando um dado é inse- rido ou atualizado no banco de dados. Antes de realizar a atividade de atualização diretamente no banco de dados em disco (que é mais demorada), essa atualização é realizada primeiramente na área de buffer, ficando disponível para outros processos e, desse modo, re- plicada para o dispositivo de disco magnético, não no exato momen- to em que ela acontece. Essas operações através de buffers atuam sempre sobre blo- cos (ou páginas) físicos de dados, que são gerenciadas pelo siste- ma operacional. Esses blocos anteriormente eram compostos por 512bytes, mas atualmente o padrão utilizado pelos fabricantes é de 4Kbytes, ou seja, 8 blocos anteriores deram origem a somente um bloco atual. Isso faz com que mais dados estejam armazena- dos em um único bloco, que uma quantidade menor de bytes de controle e sincronismo sejam consumidos, maximizando o uso do espaço físico do disco. Figura 4 Transição de blocos de 512 bytes para 4Kbytes Data ECC: = 100 Bytes Eight 512-byte legacy sectors become a single 4K-byte sector Fonte: Seagate, 2021. Conhecer todos esses elementos físicos ligados ao armazenamento de dados poderá lhe trazer uma breve compreensão de alguns recur- sos utilizados pelos sistemas gerenciadores de banco de dados para maximizar o desempenho de consultas e atualizações. Armazenamento e estruturas de dados 17 1.2 Organização de arquivos Vídeo Os dados que iremos armazenar nos mais diversos tipos de dispositi- vos de armazenamento, predominantemente em discos magnéticos, são organizados de modo a formar registros. Cada registro é, portanto, uma sequência de campos de dados elementares que agrupados formam uma unidade de leitura ou de gravação. Esses registros ocupam por sua vez espaços físicos em blocos de dados, conforme já vimos. Isto é, um bloco físico em um disco será utilizado para armazenar um certo número de re- gistros. A quantidade de registros possível de ser armazenada num bloco dependerá do tamanho total do bloco e do tamanho individual de cada registro. Imagine então que temos um bloco de 4Kbytes e um registro que ocupe 512bytes. Teríamos a possibilidade de armazenar 8 registros por bloco. Precisamos lembrar que, tanto na estrutura do bloco como na es- trutura do registro, podemos ter áreas de dados reservadaspara contro- les internos do sistema operacional, por exemplo, o número do bloco, o status do bloco etc. Outra característica relevante é o fato de que eventualmente nem to- dos os registros tenham o mesmo tamanho. Existem duas modalidades de criação de registros: os de tamanho fixo e os de tamanho variável. Os registros de tamanho fixo são originados do agrupamento de campos de tamanho fixo (todos eles) – um exemplo de campo de tamanho fixo é aquele que solicita o CEP. Já os registros de tamanho variável são ori- ginados do agrupamento de campos, onde pelo menos um deles possa ser de tamanho variável. Veremos mais a frente que nos SGBDs é muito frequente a existência de registros de tamanho variável, pois algumas das colunas que irão compor um tupla (registro) de uma tabela, poderão ter tamanho variável, ou até mesmo não possuírem conteúdo, tendo, portan- to, tamanho igual a zero. É de se imaginar que, quando os registros de dados são de tamanho fixo, o gerenciamento de espaço físico ocupado num bloco de disco seja mais fácil do que o gerenciamento de armazenamento de registros de tamanho variável. Dissemos há pouco que se um registro tem tamanho de 512bytes, então teríamos 8 registros num bloco de disco de 4Kbytes. Mas, e se cada registro tiver um tamanho? Suponha que um registro tenha 512bytes, mas que outro tenha 600bytes, e outro 300bytes. Quantos re- gistros caberiam em cada bloco? E o que aconteceria com o bloco quando um desses registros fosse atualizado e o seu tamanho fosse alterado? 18 Banco de Dados II Todo este gerenciamento de espaços é executado pelo SGBD em conjunto com o sistema operacional, de modo a permitir que registros novos sejam incluídos num bloco, registros existentes sejam alterados em seus tamanhos, ou até que registros sejam excluídos, liberando es- paços que futuramente terão de ser utilizados por novos registros, os quais devam ser armazenados no mesmo bloco. Para que isso seja possível, são criados nos blocos estruturas de controle (chamadas de header) em que o controle de espaço disponível no bloco, os espaços liberados e outros controles são todos guardados como dados de controle do bloco. Esse é mais um elemento que ocu- pará espaço em seu futuro banco de dados. Se tivermos 1.000 registros de 1.000 bytes cada, não terá um espaço físico de somente 1.000.000 bytes. Teremos que considerar também que o sistema irá criar áreas de dados de controle em cada bloco (ou página) gerenciada pelo SGBD. Porém, somente armazenar e gerenciar um conjunto de registros em um disco, não nos daria capacidade suficiente para manipulá-los lo- gicamente por meio de uma linguagem de programação. Temos então um novo elemento: o arquivo; isto é, uma reunião de vários registros formando logicamente um arquivo. Podemos dizer que o arquivo do cadastro de funcionários será a reunião de todos os registros de dados de cada um dos funcionários. Os arquivos, por sua vez, possuem um tipo de organização e estru- turação dos registros que compõem o que determina algumas caracte- rísticas associadas aos métodos de acesso que poderão ser utilizados para acessar os dados deste arquivo. Temos, então, dois possíveis mé- todos de acesso, conforme o Quadro 1.Quadro 1 Métodos de acesso Método de acesso Característica Sequencial Para acessar o registro de posição N+1 é necessário antes acessar o registro de posição N. Deverá existir um único critério de ordenação entre a coleção de registros para que possa então identificar se o registro procurado está antes ou após a posição N em que estamos. A leitura dos dados ocorre somente no sentido “para frente”. Ou seja, seguindo a ordem: N-1, N, N+1. Direto Para acessar qualquer registro, em qualquer posição, basta que se forneça um valor de uma chave de localização do registro. Poderá existir mais de um critério de ordenação entre a coleção de registros, cada um defini- do por uma diferente chave. Pode-se acessar o registro de posição N+1 sem ter previamente acessado o registro de posição N. Fonte: Elaborado o autor. Armazenamento e estruturas de dados 19 Esses métodos de acesso estarão vinculados ao tipo de organização de um arquivo que pode ser: heap (pilha), sequencial ou hash (indexa- da), cada um deles tendo vantagens e desvantagens. A organização heap é a que oferece melhor desempenho para a operação de inserção de novos registros no arquivo, pois cada novo registro irá sempre ser armazenado como o último da pilha (ao final do arquivo). Imagine que cada novo funcionário contratado teria seus dados armazenados no final do arquivo, após os dados do último fun- cionário já registrado. Porém, como não existe nenhuma ordem prees- tabelecida entre os registros, mas somente uma ordem cronológica, então a futura busca por um registro específico seria muito difícil. Onde encontraríamos, por exemplo, o funcionário de nome “João da Silva”, a funcionária de matrícula “123456”? Jamais saberíamos onde se encon- tram. Eles podem ser o primeiro ou o último registro do arquivo, pois somente a ordem de inserção é que os fez ocupar esta posição. Caso existam exclusões de registros em posições intermediárias do arquivo (e não no seu final), acabaremos por ficar com espaços inutilizados, pois o próximo registro a ser armazenado não ocupará esse espaço livre, e sim irá para o final do arquivo. A organização sequencial é uma evolução desse modelo. Ela já agre- ga o conceito de uma chave de ordenação de uma lista sequencial de registros. A inserção de novos registros deverá ser feita exatamente na posição em que a chave de ordenação defina. Se, por exemplo, já temos um registro de “Pedido de Férias” para o funcionário com a ma- trícula “0005” e logo depois outro “Pedido de Férias” para o funcionário “0015”, então quando o funcionário de matrícula “0007” solicitar suas férias, teremos que inserir esse pedido, entre o “0005” e o “0015” para que tenhamos então os pedidos: “0005”, “0007” e “0015” corretamen- te ordenados. A inserção de novos registros intercalados aos registros que já existiam exige técnicas de programação específicas. A vantagem dessa organização é que se estivermos posicionados no registro “0007”, saberemos que o registro “0015” estará mais a frente e que o registro “0005” estará mais atrás. É como procurar uma carta em um baralho que esteja organizado por naipe e números em comparação a procurar a mesma carta em um baralho que foi embaralhado aleatoriamente. A última organização de arquivos, e talvez a mais próxima daquela que um SGBD irá aplicar em seus métodos de acesso, é a organização hash (ou indexada). Como o próprio nome diz, haverá uma organização 20 Banco de Dados II dos registros que permitirá que se use o método de acesso direto. Po- deremos acessar qualquer registro de toda a coleção de registros que forma o arquivo a qualquer momento, com praticamente uma única leitura de um bloco de dados. É como se conseguíssemos identificar a trilha, o setor, o bloco e o registro dentro bloco diretamente, sem ter que passar por nenhum outro registro previamente. Além de permitir acesso direto na leitura, essa organização de arquivos também permite novas inserções de registros, alterações de tamanhos de registros, e até a exclusão de registros pode ser realizada com menor complexida- de e esforço para o SGBD e para o sistema operacional. A organização indexada surgiu como evolução da organização se- quencial, que limitava o acesso direto aos dados. Não poderíamos imaginar um sistema on-line como temos hoje, em que uma pessoa consegue acessar rapidamente o dado que deseja, sem que a organi- zação indexada tivesse sido criada. Nenhum sistema transacional seria viável se para atualizar um único registro num banco de dados, tivésse- mos que ler todos os registros anteriores ao registro que desejássemos atualizar. Também os sistemas gerenciadores de banco de dados não teriam sido viáveis sem terem sido concebidos como uma evolução dos arquivos com organização indexada.Nessa organização, além do próprio arquivo de dados, composto por seus registros e campos, teremos uma estrutura complementar de apoio para o acesso. Essa estrutura é chamada de índice de acesso. Através dela poderemos localizar um registro com o menor esforço possível. Diferentemente do arquivo sequencial, que só poderia ter uma chave de ordenação, um arquivo indexado pode ter vários arqui- vos de índices, cada um criado com base em uma chave de ordenação. Poderíamos assim, por exemplo, ter nosso cadastro de funcionários, com índices criados por “nome”, “matrícula”, “data de nascimento” etc. Cada índice deste nos permitiria fornecer um valor para o campo chave e, rapidamente, obter o registro desejado. Muitas pessoas se questionam sobre o fato de a organização se- quencial ser bastante limitada e qual o motivo dela ter sido criada e utilizada por tanto tempo. Isso se deve, na verdade, a uma questão his- tórica. Os primeiros dispositivos de armazenamento de dados que sur- giram para permitir o processamento de dados corporativos (em maior volume) foram os cartões perfurados. Eram dispositivos rudimentares Armazenamento e estruturas de dados 21 para armazenamento tanto dos códigos dos programas quanto dos da- dos de entrada para tais programas. Um conjunto de cartões era então lido sequencialmente, um cartão após o outro. Com a evolução dos dispositivos de armazenamento magnético, os cartões deixaram de ser usados, mas foram então substituídos por outro dispositivo de leitura e gravação (uma novidade) sequencial: as fitas. Figura 5 Cartões perfurados e fitas magnéticas No m ad _S ou l/S hu tte rs to ck Agora já era possível ler e gravar de modo sequencial um arquivo. Lia-se cada um dos registros da fita número 1, alterava-se o que fosse necessário, incluíam-se ou excluíam-se registros e o resultado era gra- vado na fita de saída número 2. No próximo processamento, a fita nú- mero 2 voltava a ser a fita de entrada para o próximo processamento. Ou seja: o uso do método de acesso sequencial foi uma imposição dos recursos tecnológicos que se dispunham naquele momento. 1.3 Técnicas de hashing Vídeo Como vimos acima, o acesso direto ao registro de um arquivo, ou especialmente de um banco de dados, deixou de ser uma opção e se transformou basicamente em um requisito para qualquer projeto de sistema de informação que trabalhe como transações on-line. Também vimos que, para ter acesso direto usando índices de acesso, teríamos que criar e manter estruturas adicionais além dos 22 Banco de Dados II próprios dados que armazenaremos. Isso terá dois impactos diretos nos sistemas que venhamos a criar: consumo adicional de espaço físi- co (apesar do custo estar cada vez menor no mercado) e tempo adicio- nal para processamento. Isso se deve ao fato de que com estruturas de índices sendo utilizadas, teremos que primeiro ler e processar da- dos em estruturas de índices, para depois poder através delas chegar até os dados reais, conforme demonstrado na Figura 6. Figura 6 Estrutura de índice convencional número conta nome agência valor conta A-217 Brighton 750 A-101 Downtown 500 A-110 Downtown 600 A-215 Mianus 700 A-102 Perryridge 400 A-201 Perryridge 900 A-218 Perryridge 700 A-222 Redwood 700 A-305 Round Hill 350 ÍNDICE (Nome Agência) ARQUIVO DE DADOS – CONTAS Brighton Downtown Mianus Perryridge Redwood Round Hill Fonte: Silberschatz, 2012, p. 323. Isto é, se você desejasse ter acesso às contas da agência “Downtown”, poderia fornecer o “nome da agência”, que seria então localizado na área de índices que, por sua vez, apontaria para a primei- ra conta (A-101) desta agência na área de dados. Isso significa que se faria uma primeira leitura dos dados do índice para depois localizar o item “Downtown” e então descobrir a informação que o levaria para a posição em disco onde se encontra o registro “A101”. Esse processo, apesar de ser funcional, poderia ser otimizado se pudéssemos utilizar um método mais ágil e com menor gasto de espa- ço em disco para armazenamento de índices. Este novo método cha- ma-se de hashing. Ele utiliza uma função hash. Para que possamos entender melhor o conceito do processo de hashing deveremos primeiro estabelecer o conceito de um bucket (balde). Um bucket é uma área de armazenamento de um ou mais registros. Normalmente um bucket está associado a um bloco físico, mas ele pode ser maior ou menor que um bloco. Armazenamento e estruturas de dados 23 O processo de hashing é baseado em uma função matemática que permite que, para o conteúdo de um campo de registro, possamos ge- rar um número de bucket entre uma lista de buckets disponíveis para onde ele deveria ser destinado. Vamos imaginar que temos uma lista de buckets definida por B e uma lista de valores de entrada para um campo definida por V. A função hash é uma função do tipo: B = hash (V) Isso significa que para cada valor de V, situado dentro do domínio de valores possíveis de V, fornecido para a função hash, esta será capaz de produzir um valor B, dentro do domínio de valores que B pode assu- mir. Se tivermos 1.000 valores diferente para V, e 100 valores diferentes para B (100 buckets), então uma função ideal de hash deveria ser capaz de fazer uma distribuição homogênea de 10 valores de V em cada um dos 100 buckets existentes. Figura 7 Função de hash alocando registros nos buckets ideais 001 - João da Silva 050 - Zélia de Souza 003 - João de Souza 017 - Maria Marq Bucket 1 001 – João da Silva 017 – Maria Marq Bucket 2 050 – Zélia de Souza Bucket X 003 – João de Souza Dados fornecidos Função Área de armazenamento Função hash Fonte: Elaborada pelo autor. Podemos ver na Figura 7 que tanto o nome “João da Silva” como o nome “Maria Marq” geraram o mesmo número de bucket. Isso não é um problema, pois, como vimos, um bucket será um bloco de disco e nele poderemos ter vários registros. Se para o armazenamento destes dois registros distintos eles forem direcionados para o bucket 1, então quando desejarmos acessá-los numa consulta futura, a mesma função de hash será aplicada e, ao receber o nome “João da Silva”, o SGBD po- derá automaticamente identificar que deve procurar por esse dado no bucket 1 que se encontra em disco, criando assim um mecanismo de acesso direto sem a necessidade de um índice. A eficiência desse processo de hashing está, portanto, baseada em uma função que consiga executar a melhor distribuição possível dos va- 24 Banco de Dados II lores recebidos em sua entrada, dentre todos os espaços de buckets dis- poníveis. No exemplo hipotético que demos, de nada adiantaria ter uma função em que os 1.000 registros de entrada acabassem sendo alocados em somente 10 dos 100 buckets disponíveis. Teríamos uma taxa de ocu- pação muito alta em cada bucket (100 registros por buckets) e muitos buckets vazios (90% deles). Ou seja, uma função de hashing deve ter a habilidade de fazer a dispersão homogênea dos registros recebidos. Isto poderia parecer simples de ser feito se soubéssemos o padrão de dados que receberíamos. Porém, temos que imaginar que em uma função de hashing teremos como parâmetro de entrada os mais diversos tipos de conteúdo, como um nome, um CPF, uma data, um código alfabético, um código numérico etc. O sucesso de uso de uma função de hashing depen- deria, portanto, do sucesso da função de distribuição de registros. Como isso nem sempre pode ser assegurado, temos tido então o predomínio do uso de estruturas de índices, que apesar de mais custosas em termos de espaço, podem assegurar uma taxa de sucesso maior. 1.4 Estrutura de indexação de arquivos Vídeo Como alternativa para o acesso direto aos registros de um arqui- vo, temos a possibilidade de utilizar estrutura de índices. Por isso, esta organização de arquivos era, muitas vezes, referenciada como associa- da ao termo arquivos indexados. Inicialmente os arquivos tinham uma única chave (que até poderia ser composta por vários campos) paraa qual uma estrutura de índice era construída, de modo a permitir que o acesso direto fosse realizado. Atualmente esse mesmo método de acesso é usado para acesso aos dados das tabelas em um banco de da- dos. A vantagem atual é que uma mesma tabela pode ter vários índices criados simultaneamente. O primeiro índice é aquele criado obrigatoriamente para a coluna que representa a chave primária da tabela. Ele não pode ter valores duplicados na chave (restrição de domínio) e é denominado de índi- ce primário. Os demais índices, criados então sobre as demais colunas da tabela podem ser criados com valores duplicados em suas chaves, permitindo diferentes chaves alternativas para acesso direto são deno- minados de índices secundários. O fato de um índice permitir ou não valores duplicados não é uma restrição da estrutura do índice, mas sim uma restrição do modelo relacional. Armazenamento e estruturas de dados 25 Seja para um arquivo indexado tradicional (ainda disponível em sis- temas de mainframe tradicionais existentes em grandes instituições financeiras) ou para uma tabela de um moderno banco de dados rela- cional criado com um dos mais recentes SGBDs existentes no mercado, teremos o mesmo princípio e tecnologias similares sendo utilizadas. Veremos a seguir dois tipos de arquitetura de índices que podem ser aplicados na criação de uma estrutura de acesso direto: os índices densos e os índices esparsos. Porém, primeiramente precisamos defi- nir o que é um índice e como ele opera. Um índice é uma estrutura de dados sequencial e ordenada que mantém somente os dados essen- ciais da chave de acesso a um registro, no qual temos agregado um ponteiro (campo que faz o endereçamento do registro final que será acessado) que serve de vínculo entre o índice o arquivo de dados. Figura 8 Estrutura de um índice Índice Ana Bloco 9 Cesar Bloco 5 ... ... Arquivo de dados Ana Maria 02/10/1980 Beatriz 22/05/1981 João 09/11/1992 Cesar 11/11/1997 Carlos 25/03/1962 Localizar nome = “Cesar” Fonte: Elaborada pelo autor. Essa estrutura permite que, sabendo o nome de um funcionário, por exemplo, “Cesar”, possamos fornecer este valor para o mecanismo de busca, que irá identificar no índice (estrutura sequencial e ordena- da) qual é o endereço físico onde este registro se encontra no arquivo de dados (utilizando um ponteiro). Assim, os registros no arquivo po- dem até estar dispersos, mas serão facilmente localizados, pois o índice provê ordenação e acesso imediato. O mecanismo de busca do nome “Cesar” dentro do índice poderá usar diferentes estratégias, sendo uma delas a busca em árvores binárias. Como a estrutura de índices acabará por ocupar um espaço físico em disco e precisará estar constantemente sendo reorganizada para ficar ordenada, tornou-se necessário pensar em um meio de fazer com que essa estrutura pudesse ser o menor possível. Imagine, por exem- plo, que tenhamos um arquivo com 1.000 registros. Se cada um desses 26 Banco de Dados II precisasse de uma entrada na estrutura de índices, teríamos então 1.000 chaves ordenadas no índice, ocupando um espaço X em disco. Porém, se para os 1.000 registros do arquivo, pudéssemos somente criar 250 chaves na estrutura de índice teríamos uma estrutura com 25% do uso de espaço físico para guardar todo o índice e para futura- mente percorrer o índice durante uma busca. É verdade que com esta segunda opção não conseguiríamos acessar cada um dos 1.000 regis- tros do arquivo diretamente. Teríamos sempre que localizar a chave mais próxima da chave desejada e , a partir daí, executar uma busca sequencial. Um índice denso é, portanto, uma estrutura de índices para a qual cada valor de chave no arquivo gera uma entrada distinta no índice (1000 registros com 1000 chaves no índice). Já um índice esparso, ou não denso, é uma estrutura para a qual algumas das chaves do arquivo são criadas no índice e pelo acesso a essas chaves, as chaves subse- quentes são recuperadas (1000 registros com 250 chaves no índice). Segundo Date (2004), o termo não denso refere-se ao fato do índice não conter uma entrada para cada ocorrência de registro armazenado no arquivo indexado. Apesar de os índices densos ocuparem mais espaço em disco, eles podem prover mais velocidade de acesso ao arquivo, pois, para uma dada chave, o registro é recuperado imediatamente. Já um índice esparso ocupa menos espaço em disco, porém exige um processamento adicional para se chegar ao registro desejado. Além disso, quando um índice se torna muito grande por ter que endereçar um número muito grande de registros (por exemplo, 1 mi- lhão de registros), passa a ser necessário o uso de uma estrutura de índices multinível. Imagine que tenhamos 200 mil blocos, cada um com seus 5 regis- tros indexados (exemplo de 1 milhão de registros). Teríamos então na estrutura de índice interno uma quantidade de 1 mil blocos de índices cada um apontando para até 200 blocos de dados (totalizando 200 mil apontadores para blocos de dados). Já no índice externo poderíamos ter somente 10 mil chaves de referência apontando para os 10 mil blo- cos do índice interno. Perceba que ao invés de ter um único índice com 1 milhão de entradas, teremos um índice externo com somente 10 mil chaves, capazes de chegar a 1 milhão de registros através de índices internos. No material MC202 - Estrutura de Dados você poderá ver em detalhes o processo de atualização de uma estrutura de índices baseada em uma árvore binária (Árvore-B). São exemplificadas inserções e remoções de elementos na estrutura da árvore, demonstrando como a reorganização de ponteiros é feita pelo sistema gerenciador. Pode-se compreender então a complexidade e o custo de manutenção da estrutura de índices. Disponível em: https://www. ic.unicamp.br/~afalcao/mc202/ aula13-ArvoreBinariaBusca.pdf. Acesso em: 25 nov. 2020. Leitura https://www.ic.unicamp.br/~afalcao/mc202/aula13-ArvoreBinariaBusca.pdf https://www.ic.unicamp.br/~afalcao/mc202/aula13-ArvoreBinariaBusca.pdf https://www.ic.unicamp.br/~afalcao/mc202/aula13-ArvoreBinariaBusca.pdf Armazenamento e estruturas de dados 27 Figura 9 Estrutura de índice multinível bloco de índice 0 bloco de dados 0 Índice externo Índice interno bloco de índice 1 bloco de dados 1 Fonte: Silberschatz; Korth; Sudarshan, 2012, p. 325. Como podemos imaginar, quanto maior a quantidade de registros que precise ser armazenado, maior a estrutura de índice que deverá ser criada para suportar o acesso direto a todos os registros. Uma es- trutura comumente utilizada para dar suporte a esse tipo de índice é a árvore B+, ou árvore balanceada. Segundo Silberschatz, Korth e Sudarshan (2012), a estrutura de ín- dice de árvores B+ é a mais utilizada por ser a que melhor mantém sua eficiência apesar da inserção e exclusão de dados. Um índice de árvore B+ tem a forma de uma árvore balanceada, em que cada caminho da raiz até uma folha da árvore é do mesmo tamanho. 28 Banco de Dados II Apesar da alta eficiência para localização de registros, esse tipo de estrutura sobrecarrega de certo modo o processo de inserção e exclu- são de registros, pois constantemente a árvore precisa ser balanceada, fazendo com que o SGBD tenha que, por instantes, bloquear toda a es- trutura de índices para reorganizá-lo. Desse modo, se você está inserin- do um único registro de um funcionário, toda a tabela de funcionários terá que ser bloqueada por alguns instantes indiretamente, pois o seu índice foi bloqueado para ser reorganizado. Figura 10 Estrutura de árvore B+ I K MC F (A,4) (B,8) (C,1) (D,9) (E,4) (L,4) (J,8) (K,1) (L,6) (M,4) (N,8) (P,6) (F,7) (G,3) (H,3) Fonte: Silberschatz; Korth; Sudarshan, 2012, p. 334. Cada fabricante de SGBD implementa suas estruturas e algoritmos de reorganização, tanto de espaços físicos das áreas de dados quanto das áreas de índice, de modo a procurar prover o melhor desempenhopossível em seus produtos e de se diferenciar de seus concorrentes. Muitas vezes após o lançamento de uma nova versão de um produto do mesmo fabricante de SGBD, são anunciados ganhos de performan- ce no acesso ou inclusão de registros justamente pela implementação de melhorias nesses algoritmos internos. Isso mostra que, apesar de serem conceitos e aspectos muitas ve- zes pouco considerados quando se modela e se projeta um banco de dados, e até mesmo quando se utiliza uma aplicação desenvolvida com um SGBD, esses detalhes técnicos podem sim trazer impactos no resul- tado final. Conhecer e explorar esses recursos pode resultar em um sis- tema com melhor ou pior performance em termos de tempo de acesso, ou tempo de resposta para a busca de uma informação. Armazenamento e estruturas de dados 29 CONSIDERAÇÕES FINAIS As estruturas físicas de armazenamento dos dados de um banco de dados não se distanciam muito das estruturas de armazenamento que há décadas vem sendo utilizadas para arquivos sequenciais e arquivos indexados. Com certeza, melhorias nos processos de armazenamento, nas tecnologias e nos materiais usados para o armazenamento, e o poder computacional otimizado gerado por sistemas operacionais e sistemas gerenciadores de bancos de dados, geraram novas possibi- lidades de exploração dos dados armazenados nos bancos de dados. Porém, conhecer os conceitos e princípios que regem a manipula- ção física desses dados vai nos dar condições de nos próximos capí- tulos compreender a necessidade de implementar novos controles e recursos nos sistemas gerenciadores de dados. Muitas vezes uma sim- ples limitação física imposta pelo tempo de acesso a disco, que exige um movimento mecânico do braço do leitor de disco, poderá ser usada como justificativa para que se crie um mecanismo com os buffers de acesso a dados no SGBD. O que pode parecer neste momento um conteúdo muito distante do real papel do sistema gerenciador de banco de dados, criado para dar uma grande facilidade para manuseio do banco de dados, é, na verdade, um conteúdo muito importante para compreender o próprio funcionamento do sistema gerenciador do banco de dados. ATIVIDADES 1. Justifique por que nas primeiras estruturas de arquivos criadas os pesquisadores optaram por estruturas sequenciais, sendo que já sabiam que elas não eram as que apresentariam melhor desempenho. 2. Por que um disco magnético sempre será mais lento para nos devolver um dado solicitado, se comparado a uma memória RAM? 3. Qual é a principal característica esperada de um bom algoritmo de hash? 4. Por que uma estrutura de índice, apesar de consumir espaço em disco, pode ser uma boa opção para se implementar acesso direto a um grande volume de registros? 30 Banco de Dados II REFERÊNCIAS CANAL TECH. Como funcionam os discos rígidos, 2021. Disponível em: https://canaltech. com.br/hardware/Como-funcionam-os-discos-rigidos/. Acesso em: 18 jan. 2021. DATE, C. J. Introdução a sistemas de banco de dados. São Paulo: Elsevier, 2004. ELMASRI, R; NAVATHE, S. Sistemas de banco de dados. 4. ed. São Paulo: Pearson Addison Wesley, 2006. SEAGATE. Transição para discos rígidos de formato avançado com setores de 4K, 2021. Disponível em: https://www.seagate.com/br/pt/tech-insights/advanced-format-4k-sector- hard-drives-master-ti/. Acesso em: 18 jan 2021. SILBERSCHATZ, A.; KORTH, H. F.; SUDARSHAN, S. Sistema de banco de dados. 6. ed. Rio de Janeiro: Elsevier, 2012. Processamento e otimização de consultas 31 2 Processamento e otimização de consultas Tendo modelado e construído nosso banco de dados e po- pulado os dados em suas tabelas, passamos a contar com uma estrutura que poderá ser acessada por meio da linguagem estru- turada de consultas (SQL). Os sistemas gerenciadores de bancos de dados proverão, então, algoritmos complexos e muito bem elaborados, a fim de nos munir de meios ágeis para acessar os dados mediante as SQL que iremos construir. Vamos conhecer aqui alguns aspectos ligados às estratégias de acesso utilizadas por essas ferramentas. O conhecimento desses aspectos nos permitirá identificar as eventuais causas de um comando não ter o melhor desempenho, conforme o esperado. Identificaremos também por que, algumas vezes, o próprio SGBD está construindo caminhos de acesso aos dados diferentes daqueles que imaginamos serem os ideais. Neste capítulo, observaremos, ainda, como são avaliados os custos de execução de uma consulta, de modo que possam ser aplicados algoritmos de otimização e de processamento de consultas. 2.1 Medidas de avaliação de custo de consultas Vídeo A terminologia custo de uma consulta é o primeiro conceito que devemos estabelecer. Esse conceito expressa uma medida normal- mente estabelecida em tempo ou em quantidade de leituras feitas no banco de dados para retornar um conjunto de dados solicitado. Assim, podemos estabelecer, por exemplo, que se uma consulta con- some 200 leituras para nos retornar todos os registros de funcioná- rios que foram contratados no último mês de uma tabela funcionário 32 Banco de Dados II e outra consulta consome somente 100 leituras no banco de dados para nos retornar esses mesmos registros, logo essa segunda tem um “custo” menor. Veremos, mais à frente, que outra unidade de medida é o tempo, o qual, na verdade, é diretamente dependente da própria quantida- de de leituras feitas no banco de dados, já que cada uma demanda uma unidade de tempo e, quanto mais leituras fizermos, mais tempo gastaremos. Desse modo, como você deve estar imaginando, sempre um custo menor será melhor do que um custo maior. Nossa meta, assim como a dos algoritmos utilizados pelo SGBD, será sempre reduzir o custo de uma consulta. Esse custo poderá ser continuamente medido e avalia- do, procurando identificar se durante a evolução de uso do banco de dados ele melhora ou piora. Os próprios sistemas gerenciadores de banco de dados oferecem ferramentas para que esse custo seja medido, avaliado e reduzido. É possível executar um comando de busca de um conjunto de dados e verificar qual foi o consumo de leituras para cumprir essa tarefa. Como sabemos, monitorar e otimizar a performance de acesso ao banco de dados são uma tarefa do administrador de banco de dados, e não do programador. A linguagem SQL é uma linguagem declarativa, em que se especifica quais dados se deseja obter, mas não como eles serão obtidos. Justamente por esse fato é que o programador não será o responsável por medir, avaliar e otimizar os comandos SQL que es- creve (apesar de em alguns casos poder ajudar, nesse aspecto, conhe- cendo alguns conceitos que veremos aqui), porém deverá contar com a ajuda do administrador de banco de dados para obter melhorias de desempenho nos programas que escreve. A medição e a otimização do custo de uma consulta podem ser fei- tas basicamente utilizando dois métodos: regras heurísticas e dados históricos armazenados. Veremos a seguir uma rápida caracterização de cada um deles. • Regras heurísticas Esse processo de medição e otimização de custos de consultas utiliza regras básicas, ou regras simples, estabelecidas na álgebra relacional, que é derivada da álgebra matemática, ou seja, pode ser demonstrada. Processamento e otimização de consultas 33 A álgebra relacional, segundo Date (2004, p. 193), é “um conjunto de operações e relações. Cada operação usa uma ou mais relações como seus operandos, e produz outra relação como seu resultado”. Com isso, podemos, por exemplo, demonstrar que combinar dois conjuntos de vogais e números para depois remover somente os pares que têm a vogal a tem o mesmo efeito que primeiro selecionar a vogal a e, em seguida, combinar somente ela com os números. Quadro 1 Exemplo de uma regra heurística Combinar e selecionar Selecionar e combinar · Vogais = a, e, i, o, u · Números = 1, 2, 3 · Combinação = a1, a2, a3, e1, e2, e3, i1, i2, i3, o1, o2, o3, u1, u2, u3 · Seleção onde vogal = “a” => a1, a2, a3 · Vogais = a, e,i, o, u · Números = 1, 2, 3 · Seleção onde vogal = “a” => a · Combinação = a1, a2, a3 Conclusão: combinar e selecionar = selecionar e combinar. Fonte: Elaborado pelo autor. Várias regras como essas estão disponíveis na álgebra relacional e podem ser aplicadas para otimizar o custo de uma consulta. Ima- gine que, no Quadro 1, a produção de cada uma das combinações possíveis pudesse gerar uma unidade de custo. A opção combinar e selecionar gerou 15 combinações, para depois remover delas somente três itens. Já a opção selecionar e combinar gerou só três combinações. Essa segunda opção teria um custo de consulta cinco vezes menor do que a primeira. • Dados históricos armazenados Outra estratégia que pode ser utilizada, ou até combinada com a es- tratégia das regras heurísticas, é o armazenamento de dados sobre as 34 Banco de Dados II tabelas, sobre os custos previamente identificados, sobre a frequência de uso de uma determinada consulta etc. Isto é, por exemplo, ao aces- sarmos um banco de dados, solicitando uma lista do nome de todos os funcionários e os estados onde nasceram, recebemos os dados da consulta. Porém, o SGBD aproveita o trabalho realizado para guardar informações, como as descritas a seguir. Quadro 2 Dados de uma consulta armazenados Dados obtidos e armazenados após a consulta para uso estatístico · Total de registros na tabela FUNCIONÁRIO = 1300 · Total de registros na tabela ESTADO = 27 · Total de diferentes estados referenciados por funcionários = 15 · Tempo gasto para acesso = X milissegundos · Consulta executada = muito frequentemente SQL: consultar os nomes de todos os funcionários e estados onde nasceram. Fonte: Elaborado pelo autor. Perceba que o SGBD não só foi capaz de realizar a função de devol- ver uma lista de 1.300 funcionários com seus devidos estados de nasci- mento, como também produziu uma informação estatística que pode ser usada na próxima vez que alguém desejar executar o mesmo SQL. Talvez, ao saber que somente 15 estados de um total de 27 existen- tes na tabela são referenciados, o SGBD possa escolher uma estratégia heurística melhor do que a última utilizada. Esses dados históricos fazem com que as estratégias de otimização das consultas possam ser continuamente otimizadas, enquanto o ban- co de dados vai gradativamente evoluindo em termos de novos dados armazenados, alterados ou excluídos. Segundo Silberschatz, Korth e Sudarshan (2012), temos alguns ele- mentos que determinam o custo final de uma consulta, entre eles, a quantidade de acessos ao disco, o tempo de processamento (CPU), o custo de comunicação e o próprio tempo de avaliação, enquanto outras fontes incluem também o custo de uso da memória. Vejamos cada um deles. Processamento e otimização de consultas 35 • Custo de acessos a disco Com certeza, esse é o custo mais impactante de todos os envolvidos em uma consulta ao banco de dados. Muitas vezes, ele acaba sendo o único custo avaliado e considerado, pois, caso seja reduzido, terá im- pacto sobre o custo final, que efetivamente acaba sendo o real alvo de todas as análises. Quando estudamos os aspectos do armazenamento físico de dados em dispositivos magnéticos, vimos que o tempo de latência para uma leitura em disco é infinitamente maior do que todos os demais tempos envolvidos em uma transação. Desse modo, quanto maior for a quantidade de acessos consecutivos ou esparsos ao dis- co, maior será o tempo total de transferência desses dados para a memória para o processamento. Ao se falar de custo de uma consulta, precisamos ser mais precisos e, do ponto de vista de análise de um comando SQL, temos que nos dedicar aos comandos de atualização, inclusão e exclusão de dados. Apesar de a linguagem SQL falar em consulta (palavra associada ao termo query), sabemos que ela comporta comandos para todas as funções de manipulação dos dados. Logo, nosso custo de consulta pode também representar o custo de atualização, o de exclusão e o de inclusão. Essa observação é importante, pois, se já existe um elevado cus- to associado à leitura de um bloco de dados em disco, causado pelos aspectos mecânicos e pela transferência do bloco (que pode ter tama- nhos maiores ou menores e gerar assim um tempo maior), o custo será duas vezes maior quando estivermos falando de uma inclusão ou atua- lização de registro. Isso porque, ao gravar um novo dado em disco, o sistema operacional aguarda a gravação ser finalizada e realiza uma nova leitura sobre o bloco atualizado para verificar se a gravação foi fei- ta com sucesso e se os dados estão corretamente formatados. Levando isso em consideração, cada gravação representa o dobro de tempo: o tempo de gravação e o de releitura. Sabemos que para evitar que os dados frequentemente usados se- jam constantemente acessados em disco, o sistema operacional ofere- ce uma área de buffer (ou cache), onde mantém uma cópia dos dados para um acesso mais veloz. Se por um lado isso propicia algum benefí- 36 Banco de Dados II cio, por outro, consome um tempo adicional, visto que os dados serão primeiro retirados em blocos do disco e depois movidos para o buffer, que eventualmente deverá ser reorganizado, para então serem provi- dos para o programa que os solicitou. Como dissemos, todos esses tempos compõem o tempo total de uma operação de consulta ao banco de dados. No entanto, sem dú- vidas, o tempo de latência do disco será o predominante e, por isso, qualquer redução na quantidade de leituras em disco é essencial na otimização das consultas. • Tempo de CPU Outro fator que pode ser avaliado é o tempo total de CPU consu- mido para concluir uma consulta. Essa informação também é provida pelas ferramentas de análise de performance de comandos SQL ofere- cidas pelo SGBD. Quando falamos em tempo de CPU, temos que imaginar que quan- to mais tempo a CPU trabalhar para finalizar um mesmo comando SQL, mais complexa terá sido sua execução. Talvez tenhamos uma situação em que, apesar de reduzirmos o custo de acesso ao disco, teremos um aumento no consumo de CPU para finalizar a execução do mesmo co- mando. Isso significa que tivemos menor transferência de dados entre disco e memória, mas muito mais processamento em memória. Uma vez que o tempo de processamento de CPU é muito menor do que o tempo de acesso ao disco, podemos continuar a ter a preocu- pação de buscar uma redução desse tempo (pois qualquer economia é sempre benéfica), porém sempre mantendo a visão de que reduzir 80% do tempo de CPU, enquanto o consumo de disco aumentar em somente 1%, pode não ser um benefício real ao final. Isso porque reduziremos muito um elemento com pouco impacto, em detrimento do aumento em um elemento que gera alto impacto – nesse caso, o acesso ao disco. • Custo de comunicação Com o advento do uso de bancos de dados distribuídos, ou mesmo dos bancos de dados centralizados, mas hospedados em nuvens pri- vadas ou públicas, bem como do acesso a esses bancos de dados por meio de dispositivos remotos (APPs) e de webservices, um outro ele- mento passou a ser agregado ao custo final da execução de uma con- sulta no banco de dados: o custo de comunicação. Canais para acesso Processamento e otimização de consultas 37 com maior latência (um servidor de banco de dados hospedado em outro continente pode agregar até quatro segundos de tempo de latên- cia entre receber um pedido e devolver um dado) podem representar um custo importante a ser considerado na execução de uma consulta. Uma consulta que retorne maiores volumes de dados em contraste com uma que retorne um menor volume pode acabar sendo um fator importante a ser considerado. • Tempo de avaliação Um dos elementos que pode ser utilizado para a avaliação de uma melhor estratégia para executar uma consulta é o armazenamento de dados estatísticos dessa própria consulta. Sendo assim, temos que considerar que, além de retornar os dados solicitados, o SGBD tem ain- da três trabalhos adicionais que consomem tempo: consultaros dados históricos, elaborar uma estratégia de montagem da consulta e final- mente armazenar novos dados históricos, pois o panorama pode ter se alterado desde a última consulta. Desse modo, temos um consumo de tempo adicional para que possamos otimizar nossas consultas. Normalmente, esse tempo será bem menor do que o tempo final da execução da própria consulta e o do efetivo acesso ao disco para obtenção dos dados. Portanto, po- demos considerar que é um tempo bem investido pelo SGBD e pode praticamente ser desconsiderado. • Custo de armazenamento temporário Se o acesso ao disco para leitura é demorado e o para gravação é duas vezes mais demorado, imagine a situação em que essa gravação e leitura são realizadas somente para armazenar dados temporários durante a execução de uma consulta. No Quadro 1, vimos que durante a execução de um comando SQL tínhamos a criação de um vetor tem- porário com a combinação das vogais com os números. Isso gera uma área de armazenamento temporário de dados, a qual pode represen- tar muitos megabytes de dados, considerando, por exemplo, a combi- nação de duas tabelas bastante grandes e a geração de um produto cartesiano (combinação completa) entre elas. Estamos, então, falando de um consumo elevado de tempo para gravação e leitura de dados em disco que sequer serão utilizados ao final da execução do comando, ou que nem ao menos serão vistos por quem solicitou os dados finais. 38 Banco de Dados II Após termos visto os principais elementos geradores de consumo de recursos – principalmente tempo – na execução de uma consulta, podemos imaginar que pequenos ganhos podem ser significativos a partir do momento que uma consulta tenha uma grande frequência de execução. Alguns segundos reduzidos em uma única consulta ou al- guns acessos ao disco que não sejam realizados podem significar mui- tas horas de processamento reduzido e, principalmente, uma maior performance não só para a transação em análise, mas também para as demais transações do banco de dados. Precisamos lembrar que estamos falando de um recurso finito e compartilhado. Isto é, o mesmo SGBD que não executa uma consulta de modo otimizado prejudica todas as outras transações que executam consultas otimizadas. O tempo que ele dedica às transações com alto consumo de recursos é subtraído do tempo e dos recursos que poderia oferecer às demais consultas. O cuidado com esses aspectos é uma preocupação contínua do administrador de banco de dados, que deve monitorar o desempenho de cada consulta, podendo atuar de modo top-down, ou seja, reconhe- cendo algumas transações mais consumidoras de recursos e, em se- guida, as decompondo em unidades menores até chegar a comandos específicos executados por um programa ou uma função específica. Dessa maneira, ele deverá propor ajustes que podem ir desde mudanças no modelo de dados relacional (criação de novas tabelas, desnormalização, criação de índices etc.), passando por alterações no código das aplicações e chegando até as mudanças na infraestrutura de execução do SGBD (aumento de memória e de quantidade de CPUs, processamento paralelo etc.). De modo geral, alguns cuidados e estratégias são adotados para o caso de grandes bancos de dados, que são aqueles cujas tabelas armazenam muitos registros (centenas de milhões). Uma dessas es- tratégias é a recomendação de que os dados sejam segmentados, o volume de armazenamento seja reduzido, as informações históricas não estejam on-line o tempo todo, as consolidações de dados sejam geradas, entre outras. Já para bancos de dados de pequeno volume, talvez seja muito mais efetivo o processo de otimização de consumo de recursos de compu- tação, e não necessariamente o de redução de acessos ao disco, visto No vídeo Análise de Desempenho de Consultas SQL em Banco de Dados Oracle, publicado pelo ca- nal de Leonardo Mairene Muniz, é possível ver exemplos do processo de monitoração dos planos de execução de coman- dos SQL sendo executa- dos no gerenciador de banco de dados Oracle. A análise do resultado de cada comando é comen- tada e demonstrada com base nos dados indicados em tela pelo SGBD. Disponível em: https://youtu. be/I604SeSK_d8. Acesso em: 26 nov. 2020. Vídeo https://youtu.be/I604SeSK_d8 https://youtu.be/I604SeSK_d8 Processamento e otimização de consultas 39 que parte significativa desses dados poderão estar em buffer, quase todo o tempo, reduzindo a latência geral. Além disso, caso o banco de dados tenha uma forte dependência da camada de comunicação, seja distribuído, ou tenha acesso remo- to, uma atenção especial deve ser dedicada ao tempo de latência da camada de comunicação. É nítido que, eventualmente, teremos um banco de dados de grande ou pequeno volume que também depen- derá fortemente de uma camada de comunicação. Nesses casos, um conjunto de iniciativas será necessário para equalizar os elementos geradores de alto consumo de recursos e tempo na execução das consultas. 2.2 Avaliação de expressões Vídeo A avaliação de expressões da álgebra relacional tem correlação direta com a otimização dos comandos SQL que serão submetidos à execução pelo SGBD. Ao ser elaborado um comando SQL para recupe- ração ou atualização de dados, por exemplo, temos em sua estrutura boa parte das funções da álgebra relacional, como a seleção, projeção, junção, entre outras. Nos próximos exemplos será importante ter a correta interpreta- ção das expressões, a fim de poder perceber de que modo elas podem ser otimizadas ou quais regras o SGBD aplica para transformar essas expressões. No quadro a seguir veremos algumas das principais operações, suas características e aplicabilidades. Quadro 3 Operações da álgebra relacional (lista parcial) Operação Símbolo Sintaxe Seleção ou restrição σ σ condição (Relação) Projeção π π lista de atributos (Relação) União ∪ Relação 1 ∪ Relação 2 Interseção ∩ Relação 1 ∩ Relação 2 Produto cartesiano Χ Relação 1 Χ Relação 2 Junção |Χ| Relação 1 |Χ| Relação 2 Fonte: Elaborado pelo autor. 40 Banco de Dados II • Características das operações 1. Seleção σ: seleciona tuplas (linhas) que satisfazem certa condição. Indicada pela letra grega sigma, é uma operação que, dentro de um conjunto originalmente fornecido, gera um subconjunto com a mesma estrutura, mas apenas com os elementos do conjunto original que atendem à condição estabelecida. A seleção realiza uma filtragem de linhas de uma tabela. Relação R1: Nome Data de nascimento Estado de nascimento José 25/03/1962 PR Maria 11/07/1964 SC Pedro 11/11/1997 PR Aplicando a operação: σ estado de nascimento = SC (R1), temos: R2: Nome Data de nascimento Estado de nascimento Maria 11/07/1964 SC 2. Projeção π: mantém somente os atributos solicitados na relação de saída. Indicada pela letra grega pi, gera um conjunto de saída, contendo uma tupla para cada tupla de entrada, porém possuindo somente os atributos informados na lista de argumentos da operação. A projeção realiza uma filtragem de colunas de uma tabela. Relação R1: Nome Data de nascimento Estado de nascimento José 25/03/1962 PR Maria 11/07/1964 SC Pedro 11/11/1997 PR Aplicando a operação: π nome, estado de nascimento (R1), temos: Processamento e otimização de consultas 41 R2: Nome Estado de nascimento José PR Maria SC Pedro PR 3. Produto Cartesiano Χ: gera a combinação de tuplas de duas relações. O resultado do produto cartesiano de duas relações quaisquer é uma terceira relação contendo todas as combinações possíveis entre os elementos das relações originais. Na relação gerada pelo produto cartesiano, teremos um total de linhas resultante, que é a multiplicação do total de linhas da Relação R1 com o total de linhas da Relação R2. Em cada linha produzida, teremos todas as colunas da Relação R1 agregadas a todas as da Relação R2. Essa é uma operação denominada binária, ou seja, ela combina duas relações. Relação R1: Nome Data de nascimento Estado de nascimento José 25/03/1962PR Maria 11/07/1964 SC Pedro 11/11/1997 PR Relação R2: Produto Valor 001 R$ 10,00 005 R$ 12,00 Aplicando a operação: R1 Χ R2, produzimos: R3: Nome Data de nascimento Estado nascimento Produto Valor José 25/03/1962 PR 001 R$ 10,00 Maria 11/07/1964 SC 001 R$ 10,00 Pedro 11/11/1997 PR 001 R$ 10,00 José 25/03/1962 PR 005 R$ 12,00 Maria 11/07/1964 SC 005 R$ 12,00 Pedro 11/11/1997 PR 005 R$ 12,00 42 Banco de Dados II 4. União ∪: retorna a união das tuplas de duas relações R1 e R2. Une todas as linhas da relação R2 às da relação R1, removendo as eventuais duplicatas. A quantidade e as características dos atributos entre as relações devem ser similares. A relação resultante terá também os mesmos atributos em igual quantidade e características. Relação R1: Nome Data de nascimento Estado de nascimento Eliana 25/03/1962 PR Maria 11/07/1964 SC Karla 11/11/1997 PR Relação R2: Nome Data de nascimento Estado de nascimento Eliana 25/03/1962 PR Ricardo 14/08/1984 SP Humberto 10/02/2009 RJ João 08/08/2010 SP Aplicando a operação: R1 ∪ R2, produzimos: Nome Data de nascimento Estado de nascimento Eliana 25/03/1962 PR Maria 11/07/1964 SC Karla 11/11/1997 PR Ricardo 14/08/1984 SP Humberto 10/02/2009 RJ João 08/08/2010 SP 5. Interseção ∩: gera uma relação com as tuplas comuns a R1 e R2. Essa operação produz como resultado uma relação que contém, sem repetições, todos os elementos que são comuns às duas tabelas fornecidas como operandos. As tabelas também devem possuir o mesmo número de colunas e as características semelhantes. Processamento e otimização de consultas 43 Relação R1: Nome Data de nascimento Estado de nascimento Eliana 25/03/1962 PR Maria 11/07/1964 SC Karla 11/11/1997 PR Relação R2: Nome Data de nascimento Estado de nascimento Eliana 25/03/1962 PR Ricardo 14/08/1984 SP Karla 11/11/1997 PR João 08/08/2010 SP Aplicando a operação: R1 ∪ R2, obtemos: R3: Nome Data de nascimento Estado de nascimento Eliana 25/03/1962 PR Karla 11/11/1997 PR 6. Junção Natural |Χ|: retorna à combinação de tuplas de duas relações R1 e R2 que satisfazem a uma regra de correlação. Diferentemente do produto cartesiano, essa operação estabelece um vínculo entre a relação R1 e a relação R2 por meio de um ou mais atributos em comum (criando um vínculo), e não simplesmente combinando todas as tuplas de uma relação com as tuplas de outra. Somente as tuplas que têm uma vinculação em um ou mais atributos serão combinadas. Relação R1: Nome Data de nascimento Estado de nascimento Produto comprado José 25/03/1962 PR 001 Maria 11/07/1964 SC 005 Pedro 11/11/1997 PR 001 44 Banco de Dados II Relação R2: Produto Valor 001 R$ 10,00 005 R$ 12,00 Aplicando a operação: R1 |Χ| R2 por meio do atributo/produto, produzimos: R3: Nome Data de nascimento Estado de nascimento Produto comprado Produto Valor José 25/03/1962 PR 001 001 R$ 10,00 Maria 11/07/1964 SC 005 005 R$ 12,00 Pedro 11/11/1997 PR 001 001 R$ 10,00 Nos exemplos, pudemos ver a execução de operações relacionais isoladas – assim, uma ou mais relações eram submetidas a somente uma operação de cada vez, produzindo uma nova relação de saída. No entanto, a realidade mais comumente encontrada em situações do dia a dia é aquela em que diversas operações relacionais são executadas em conjunto, uma condicionada à execução da outra. Nesse caso, temos que estabelecer uma ordem de precedência para a avaliação e execução de cada uma das operações, de modo a obter o resultado desejado, porém tendo o desempenho mais adequado. Segundo o exemplo dado por Silberschatz, Korth e Sudarshan (2012), considere a expressão da álgebra relacional para a consulta: “encontrar os nomes de todos os clientes que tenham uma conta em qualquer agência localizada no Brooklyn”. π nome-cliente (σ cidade-agência = Brooklyn (agência |Χ| (conta |Χ| depositante) A representação dessa expressão também pode ser feita por meio de uma estrutura gráfica, chamada de árvore de operação, conforme a figura a seguir. Processamento e otimização de consultas 45 Figura 1 Representação gráfica da expressão da álgebra relacional π σ |Χ| |Χ| nome_cliente agência conta depositante cidade_agência = Brooklyn Fonte: Silberschatz; Korth; Sudarshan; 2012, p. 383. Nesse exemplo fica evidente que temos quatro operações relacio- nais a serem executadas. A análise desse tipo de estrutura requer, além das otimizações possíveis, uma ordem de precedência. A execução das operações deve ser sempre realizada nos nós mais inferiores da ár- vore – esses que, após produzirem seus resultados, alimentam os nós imediatamente superiores e assim por diante até que atinjam a raiz. Assim sendo, só podemos executar a projeção depois de ter execu- tado a seleção, que por sua vez só pode ser executada depois da jun- ção entre as relações de agência, conta e depositante ser feita. Temos, então, que começar executando a junção entre depositante e conta para que, ao obter esse resultado, possamos combiná-lo com a relação agência, produzindo um novo resultado, o qual será submetido à se- leção, retornando mais um novo resultado, que por fim terá sobre ele aplicada a operação de projeção. São justamente esses resultados intermediários das operações exe- cutadas anteriormente, os quais precisam ser repassados para os ní- veis superiores, que podem se utilizar de dois tipos de estratégias do sistema gerenciador de banco de dados: a materialização de relações temporárias ou a passagem por pipeline (canalização de resultados). Na materialização de resultados, são todos gravados em discos em relações temporárias gerenciadas pelo SGBD. Nessa estratégia, temos, portanto, um grande volume de operações de gravação e leitura em disco, as quais sabemos que são os pontos de maior causa de lentidão 46 Banco de Dados II no processamento de um comando SQL. Cada relação temporária será inteiramente gravada em disco para, depois, já na próxima fase, ser to- talmente lida e processada. Dessa maneira, temos um processamento baseado na passagem de relações de uma operação para outra. Com o intuito de evitar todo esse grande volume de gravações e leituras físicas em disco, eis que surge uma nova estratégia, chamada de pipeline ou canalização de resultados. Nessa estratégia, ao invés de serem geradas relações intermediárias para armazenamento dos resultados nos níveis mais inferiores das árvores de operações, esses resultados são passados para os níveis superiores, tupla por tupla, e não mais como relações. Evita-se, desse modo, ter que produzir toda uma relação – por exemplo, para 10.000 tuplas – para então repassar todo esse conjunto. Assim, pode-se produzir a tupla 1 e passá-la au- tomaticamente para o nível superior da árvore para que ela seja pro- cessada no nível superior, enquanto o nível inferior volta a trabalhar produzindo a tupla 2, e assim por diante. É como se uma tupla gerada no nível mais inferior da árvore fosse canalizada e seguisse até a raiz da árvore, passando por um túnel onde cada uma das operações seria executada sobre essa tupla. Logo atrás dela viria outra tupla, também seguindo o mesmo canal, até que todas as 10.000 tuplas do exemplo fossem processadas uma a uma pela canalização. Essa estratégia se mostra muito mais produtiva e apresenta um de- sempenho muito melhor, principalmente quando cada uma das ope- rações da árvore pode ser alocada em diferentes threads (processos) e, também, quando essas threads podem se aproveitar de múltiplos processadores (CPUs), gerando uma capacidade de criar o paralelismo entre níveis da árvore. Porém, infelizmente, nem sempre ela se mostra viável; nesses casos, o sistema gerenciador de banco de dados volta a utilizar a materialização como alternativa. Outro aspecto relativo à avaliação das expressões da álgebra rela- cional diz respeito à análise de precedência dos operadores lógicos. Como já vimos, quando submetemos uma SQL complexa, ela acaba sendo decompostae executada em uma certa ordem. No entanto, mesmo já sendo decomposta, a expressão pode ainda ser complexa por apresentar diversos operadores lógicos. Vamos imaginar, como exemplo, uma operação de seleção que, mesmo já estando no seu for- mato básico, continua apresentando um operador lógico composto por cláusulas como NOT, AND, OR etc. Processamento e otimização de consultas 47 Nesse contexto, o operador NOT é avaliado por primeiro, em seguida o operador AND e por fim o operador OR. Caso existam operadores aritméticos e bit a bit, eles serão tratados antes dos ope- radores lógicos. Essa ordem pode, entretanto, ser alterada com o uso de parênteses. Exemplo 1 – Tratamento de precedências de operadores lógicos σ produto ( código = 20 or código = 21 and valor not = 0) Fonte: Elaborado pelo autor. No Exemplo 1, a interpretação correta, dada a ordem de precedên- cia, é de que somente o produto 21 deve ter saldo diferente de zero. O produto 20 será recuperado independentemente do valor existente no cadastro. Se nossa necessidade fosse de somente recuperar os pro- dutos 20 e 21 caso ambos tivessem valor diferente de zero, deveríamos utilizar os parênteses, assim como no Exemplo 2. Exemplo 2 – Tratamento de precedências com parênteses σ produto ( (código = 20 or código = 21) and valor not = 0) Fonte: Elaborado pelo autor. Desse modo, com a inclusão de parênteses na sintaxe do coman- do, estamos modificando a interpretação de nossa seleção, sendo que agora tanto os produtos de código 20 como os de 21 devem ter o valor diferente de zero. No Guia da arquitetura de processamento de consultas, material dispo- nibilizado pela Microsoft, você poderá ver em detalhes o processo de análise e processamento de instruções SQL pelo sistema gerenciador de banco de dados Microsoft SQL Server. Diversos exemplos e dicas sobre como realizar a tarefa de otimização são apresen- tados. Disponível em: https:// docs.microsoft.com/pt-br/ sql/relational-databases/ query-processing-architecture- guide?view=sql-server-ver15. Acesso em: 26 nov. 2020. Leitura 2.3 Algoritmos para processamento e otimização Vídeo O processamento de consultas envolve três atividades distintas que têm, cada uma, extrema importância para a obtenção do resultado de- sejado no menor tempo possível e com o melhor desempenho. A primeira atividade é a tradução das consultas escritas em lingua- gens de alto nível (SQL) para expressões que possam ser implemen- tadas pelo sistema gerenciador de banco de dados. Essa atividade é necessária, pois o SQL é uma linguagem declarativa, ou seja, ela não es- https://docs.microsoft.com/pt-br/sql/relational-databases/query-processing-architecture-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/query-processing-architecture-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/query-processing-architecture-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/query-processing-architecture-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/query-processing-architecture-guide?view=sql-server-ver15 48 Banco de Dados II pecifica os caminhos que devem ser seguidos para se obter os dados, mas somente o que se deseja obter. Isso facilita a tarefa de programa- ção, porém transfere para o sistema gerenciador do banco de dados a responsabilidade de encontrar os melhores caminhos a ser seguidos a cada SQL recebido. A segunda atividade é otimizar as expressões, geradas na etapa an- terior, usando estratégias que basicamente visam diminuir o acesso às tabelas existentes e a geração de relações temporárias em disco ou até mesmo em memória. A definição do melhor caminho, ou da melhor es- tratégia, utiliza regras heurísticas e estatísticas previamente coletadas do banco de dados para criar planos de execução do SQL. Esses planos podem ser inspecionados pelo administrador de banco de dados com o intuito de avaliar se uma SQL, ou se algum tipo de modificação na própria estrutura do banco de dados, como a criação de um novo índi- ce, pode ser requerida. Figura 2 Fluxo do processo de otimização e processamento de consultas consulta expressão da álgebra relacional plano de execução saída da consulta analisador e tradutor otimizador dados mecanismo de avaliação estatísticas sobre dados Fonte: Silberschatz; Korth; Sudarshan, 2012, p. 357. A terceira atividade é, dentre os planos definidos para o acesso aos dados, avaliar aquele que melhor resultado trará em termos de de- sempenho. Eventualmente, as próprias estatísticas existentes sobre os dados já podem ter sido alteradas, e então esse processo coleta novos dados para realimentar a atividade de otimização em uma pró- xima execução. Processamento e otimização de consultas 49 Para a etapa de otimização das consultas serão aplicadas algumas regras heurísticas básicas. Uma delas é aplicar primeiro as operações que reduzem o tamanho dos resultados intermediários, como a sele- ção e a projeção. A seleção, por exemplo, reduz o total de tuplas de uma relação; já a projeção diminui a quantidade de atributos das tu- plas. Caso tenhamos possibilidade de executar essas operações o mais cedo possível, as próximas operações que venham a produzir relações temporárias terão muito menor consumo de acesso a disco para ler e gravar dados temporários. Outro exemplo de estratégia de otimização de SQLs seria executar, o quanto antes, as operações de seleção e junção mais restritivas. Dessa maneira, caso existam duas seleções, onde a primeira resultará em um conjunto de 10 mil tuplas para, depois, ter esse resultado submetido a outra seleção, a qual resultará em somente mil tuplas, poderíamos então inverter a ordem de execução das seleções, produzindo uma re- lação temporária já com mil tuplas. Podemos ainda contar com várias regras de equivalência algébrica relacional, assim como temos na álgebra numérica. Por exemplo, sa- bemos que a multiplicação de A × B é igual a multiplicação de B × A. O mesmo princípio se aplica à álgebra relacional. Veremos a seguir alguns exemplos de equivalência que são utilizados pelo gerenciador de ban- co de dados para otimizar SQLs. • Cascata de seleções: caso exista uma única seleção na qual vários operadores (AND, OR, NOT) são utilizados, podemos transformar essa seleção em seleções individuais, cada uma com um único operador. Assim: σ A1=X and A2>0 é equivalente a σ A1=X ( σ A2 > 0). • Comutatividade de seleções: caso existam seleções encadea- das – em uma ordem Seleção 1, Seleção 2 –, podemos alterar a ordem das seleções sem impacto no resultado. Assim: σ A1=X (σ A2 > 0) é equivalente a σ A2 > 0 (σ A1 = X). • Cascata de projeções: caso existam duas ou mais projeções sen- do executadas sobre uma mesma relação, todas as projeções, com exceção da primeira, podem ser ignoradas. 50 Banco de Dados II Assim: π A1 (π A2 (π A3) Relação X é equivalente a π A1 Relação 1. • Comutatividade de seleções e projeções: caso exista um enca- deamento onde uma seleção precede uma projeção, podemos inverter a ordem dessas operações, fazendo com que a projeção preceda a seleção. O contrário também é verdadeiro. Assim: π A1 ( σ A2=X) é equivalente a σ A2=X (π A1) e σ A2=X (π A1) é equivalente a π A1 (σ A2=X ). • Comutatividade de junções ou produtos cartesianos: estabe- lece que tanto nas junções como nos produtos cartesianos a or- dem das relações envolvidas pode ser invertida. Assim: R1 |Χ| R2 é equivalente a R2 |Χ| R1. Esses são somente alguns dos exemplos de equivalências, entre tantos outros existentes, sendo utilizados pelos SGBD para otimizar as estruturas de operadores relacionais gerados a partir de uma SQL. Na prática, usar uma estrutura de equivalência pode significar, por exem- plo, reduzir drasticamente o consumo de processamento, de espaço em disco para relações temporárias e principalmente de tempo de processamento. Vamos imaginarum caso em que uma estrutura originalmente deri- vada de uma SQL tenha produzido a seguinte sequência de operações: 1. Recuperar todas as contas-correntes de todos os clientes. Isso resultaria em acessar 100.000 tuplas da relação conta- -corrente e produzir uma primeira relação temporária 1 em disco, contendo 100.000 tuplas cada uma com 20 atributos. 2. Combinar todas essas contas com os dados de seus clientes. Esse ato implicaria em ler todas as 100.000 tuplas da relação temporária 1 e combiná-las com outras 90.000 tuplas – conside- rando que alguns clientes têm mais de uma conta e que o ban- co possui um cadastro com 150.000 clientes, sendo que alguns não têm mais conta-corrente ativa –, gerando uma nova relação temporária 2 com 100.000 tuplas, porém com novos 30 atribu- tos vindos da relação cliente (consumindo ainda mais espaço em disco). Processamento e otimização de consultas 51 3. Selecionar somente os clientes que têm saldos maiores de R$ 50.000,00. Isso acarretaria ler todas as 100.000 tuplas da relação tempo- rária 2, verificando no atributo saldo quais atendem ao quesito valor, e produziria uma nova relação temporária 3 agora com somente 5.000 tuplas, mas ainda com 50 atributos (conside- rando que somente 5.000 contas-correntes têm saldo maior que R$ 50.000,00). 4. Retornar somente o saldo e nome dos clientes. Essa ação resultaria em ler todas as 5.000 tuplas da relação temporária 3, cada uma com 50 atributos, para depois pro- duzir uma relação de saída com somente 5.000 tuplas e dois atributos. Perceba que partimos de 100.000 tuplas com 50 atributos, sendo gravados e lidos em disco, para então chegar a uma relação de so- mente 5.000 tuplas com dois atributos. Algumas das otimizações possíveis seriam as apresentadas a se- guir. Elas reforçam o conceito apresentado por Elmasri e Navathe (2006, p. 368), ao afirmarem que “uma das principais regras heu- rísticas é aplicar as operações SELECT e PROJECT antes de aplicar o JOIN ou outras operações binárias. Isso se deve ao tamanho do arquivo resultante de uma operação binária – tal como o JOIN –, que geralmente é uma função multiplicativa dos tamanhos dos arquivos de entrada”. Otimizações possíveis: • realizar inicialmente uma seleção sobre as contas-correntes que tivessem saldo superior a R$ 50.000,00 para que todas as próximas relações temporárias já tivessem somente 2.000 tu- plas, mesmo sem realizar a junção desses dados com os dos clientes; • ainda antes de realizar a junção dos dados dos clientes com os dados das contas-correntes, realizar as projeções dos atribu- tos nome do cliente e saldo da conta para, então, reduzir o nú- mero de atributos manipulados nas próximas fases (reduzindo o espaço em disco). 52 Banco de Dados II Isso faria com que tivéssemos o seguinte cenário: 1. Selecionar somente as contas-correntes com saldo superior a R$ 50.000,00. Isso resultaria em uma relação temporária 1 com somente 2.000 tuplas, porém ainda com 20 atributos. 2. Realizar a projeção do atributo saldo na relação temporária 1. Essa ação implicaria em uma relação temporária 2, com somente 2.000 tuplas e 1 atributo. 3. Realizar a junção entre as contas-correntes e os dados dos clientes. Isso acarretaria uma relação temporária 3, com somente 2.000 tuplas e 31 atributos. 4. Realizar a projeção do atributo nome do cliente e saldo na relação temporária 3. Esse ato resultaria em uma relação final, com somente 2.000 tu- plas e 2 atributos. Perceba que não fizemos a projeção do atributo nome do clien- te como etapa 3 de otimização. Aqui teríamos que escolher entre ler as 150.000 tuplas da relação cliente e gerar uma relação tem- porária com 150.000 tuplas, porém com somente um atributo, ou então prosseguir somente com 90.000 tuplas dos clientes que têm contas-correntes com saldo maior que R$ 50.000,00, mas mantendo 30 atributos em cada tupla. O que definiria a escolha de uma ou outra estratégia seria a quanti- dade de bytes final que teríamos na opção 1 e na opção 2. Caso, entre os 30 atributos mantidos, tivéssemos muitos atributos curtos (poucos bytes), poderia ser melhor gerar uma relação temporária com 90.000 tuplas e 30 atributos. Já se, entre os 30 atributos, houvesse muitos atributos longos (bastante bytes), então seria melhor optar por gerar uma relação temporária de 150.000 tuplas com somente um atributo (o nome do cliente). Todos esses elementos são constantemente avaliados com base em dados históricos sobre as tabelas do banco de dados, suas caracterís- ticas, suas colunas, seus tipos de dados, sua volumetria etc. É assim que o melhor caminho de acesso será, então, definido pelo módulo de otimização de SQLs do seu SGBD. O Um guia para processa- mento de consulta de tabelas com otimização de memória, disponibili- zado pela Microsoft, faz um comparativo entre o modo de otimização de consulta com pro- cessamento baseado em disco e aquele com pro- cessamento baseado em memória. São técnicas diversas que têm suas aplicabilidades e mere- cem ser conhecidas. Disponível em: https://docs. microsoft.com/pt-br/sql/ relational-databases/in-memory- oltp/a-guide-to-query-processing- for-memory-optimized- tables?view=sql-server-ver15. Acesso em: 26 nov. 2020. Leitura https://docs.microsoft.com/pt-br/sql/relational-databases/in-memory-oltp/a-guide-to-query-processing-for-memory-optimized-tables?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/in-memory-oltp/a-guide-to-query-processing-for-memory-optimized-tables?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/in-memory-oltp/a-guide-to-query-processing-for-memory-optimized-tables?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/in-memory-oltp/a-guide-to-query-processing-for-memory-optimized-tables?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/in-memory-oltp/a-guide-to-query-processing-for-memory-optimized-tables?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/in-memory-oltp/a-guide-to-query-processing-for-memory-optimized-tables?view=sql-server-ver15 Processamento e otimização de consultas 53 CONSIDERAÇÕES FINAIS O processamento e a otimização de consultas, como pudemos ver, são uma tarefa bastante complexa, realizada pelo sistema gerenciador de banco de dados. Ela se utiliza de diversas regras, estratégias, planos, dados históricos, informações do dicionário de dados e, inclusive, dife- renciais que cada fabricante agregará de modo a tornar seus algoritmos melhores que os dos seus concorrentes. Quase todos os sistemas gerenciadores de bancos de dados aca- bam por oferecer basicamente o mesmo repertório de comandos e recursos, portanto o que os diferenciará de seus concorrentes será o fato de apresentarem um melhor desempenho no processamento de suas consultas – lembre-se sempre que o termo consulta representa qualquer comando SQL. O módulo de otimização e processamento de consultas acabará por representar indiretamente a capacidade de um sistema gerenciador de banco de dados para atender melhor às demandas dos sistemas de infor- mação, que, em última análise, desejam sempre, e cada vez mais, tempos menores para acesso e processamento de dados. ATIVIDADES 1. Por que um comando SQL não pode ser executado exatamente do modo como foi escrito? 2. Quais são os dois tipos de estratégias utilizados por um SGBD para escolher o melhor plano de execução de um comando SQL e, entre eles, qual o melhor? 3. Por que as operações de seleção e de projeção devem ser executadas antes da operação de junção e produto cartesiano? 4. Qual a similaridade entre uma operação de multiplicação de dois números na álgebra numérica e uma operação de produto cartesiano na álgebra relacional? REFERÊNCIAS DATE, C. J. Introdução a sistemas de banco de dados. Rio de Janeiro: Elsevier, 2004. ELMASRI, R., NAVATHE, S. Sistemas de banco de dados. 4. ed. São Paulo: Pearson AddisonWesley, 2006. SILBERSCHATZ, A., KORTH; H. F., SUDARSHAN, S. Sistema de banco de dados. 6. ed. Rio de Janeiro: Elsevier, 2012. 54 Banco de Dados II 3 Gerenciamento de transações Quando os primeiros sistemas de informação foram criados, em sua grande maioria, eles se utilizavam do processamento em lote (ou batch), que consistia em uma sequência de programas, sendo executados um após o outro, para atualizar dados em estruturas sequenciais ou gerar relatórios. Após algum tempo e com a evolução dos recursos para acesso on-line aos arquivos existentes, passamos a uma nova topologia de sistemas que permitem o acesso em tempo real às fontes de informação disponíveis. Porém, ainda nessa fase, o acesso era feito em modo monousuário, ou seja, cada vez que uma aplicação era executada por uma pessoa, ela tornava o compartilhamento desses dados indisponíveis para os demais usuários. Com a adoção de bancos de dados e com sua característica natural de prover o compartilhamento de dados, surge uma to- pologia denominada sistemas multiusuários, em que vários pro- cessos de consulta e atualização de dados passam a ser feitos simultaneamente por diversos usuários em diferentes pontos da rede. Juntamente a essa topologia vem um novo problema a ser resolvido: como garantir que diferentes processos de atualiza- ção e consulta de um mesmo dado possam ser realizados de maneira controlada e íntegra? Surge, assim, todo um conjunto de recursos dentro dos sistemas gerenciadores de banco de dados voltados para o gerenciamento de transações. Esse é o tema deste capítulo. Gerenciamento de transações 55 3.1 Conceitos de transações Vídeo Para se implementar um correto gerenciamento de transações, o primeiro ponto a ser definido é o conceito da própria transação. O que envolve uma transação? Qual é a sua duração? Quantas tabelas ou co- lunas ela envolve? E assim por diante. Por definição, uma transação é genericamente um conjunto de operações realizadas sobre o banco de dados, formando uma unida- de lógica de trabalho, e deve ser mantida íntegra. Isso significa que podemos ter transações envolvendo muitas ou poucas operações e muitas ou poucas tabelas, tendo ainda uma longa duração ou não. Um exemplo típico de uma transação seria uma operação de transferência de fundos entre duas contas-correntes. Essa transação bancária seria também uma transação do ponto de vista do gerencia- mento de banco de dados. Para que o processo de transferência fosse considerado concluído, teríamos que iniciar pela localização da conta de origem do dinheiro, validando se ela tem um saldo positivo. Depois, localizaríamos a conta de destino do dinheiro, verificando se ela está ativa. Em seguida, faríamos o débito do valor da conta de origem e atualizaríamos seu saldo, realizando o crédito na conta de destino e atualizando seu saldo novamente, para então gerar um registro do dé- bito no histórico de movimentação da conta de origem e, finalmente, criar um novo registro de histórico do crédito do mesmo valor na conta de destino. Tivemos, nesse exemplo, oito operações sequenciais execu- tadas no banco de dados. Mas, o que aconteceria se, durante uma dessas operações, tivésse- mos qualquer interrupção de conexão com o banco de dados? E se o débito já tivesse sido feito, mas o crédito ainda não houvesse sido con- cretizado? Teríamos, com isso, uma inconsistência no banco de dados, uma vez que o dinheiro sairia de uma conta, mas não chegaria na outra. Assim como nesse exemplo, vários outros processos do dia a dia, que são implementados por um programa utilizando um banco de da- dos, requerem múltiplos acessos e várias atualizações em diferentes tabelas, colunas e linhas para que sejam considerados como executa- dos com sucesso. 56 Banco de Dados II Como, então, podemos informar ao sistema gerenciador de banco de dados onde começa nossa transação (a primeira opera- ção que dará início ao nosso conjunto de oito operações) e onde essa transação termina (a última operação do nosso conjunto de oito operações)? Segundo Silberschatz, Korth e Sudarshan (2012), uma transação deve ser delimitada pelas instruções de begin transaction e end transaction. Esses dois comandos são providos permitindo ao sistema gerenciador de banco de dados sinalizar que todos os demais comandos SQL que seguem o begin transaction es- tarão agregados em uma única transação, até que se encontre então um end transaction. Lembre-se de que esses comandos SQL estarão inseridos em uma linguagem hospedeira ou, como cita Date (2004, p. 40), “uma lingua- gem convencional de programação”, que, por sua vez, também terá outros comandos nativos da própria linguagem hospedeira 1 , delimita- dores da transação. Em nosso exemplo de uma transação bancária de transferência de fundos, temos, além dos acessos e das atualizações ao banco de dados, comandos que, com base no saldo atual e no valor debitado, calculam o novo saldo. Do mesmo modo, de acordo com o saldo atual e o valor creditado, calculam o novo saldo após o crédito. O sistema gerenciador de banco de dados deve garantir que uma transação seja executada de modo completo e validada pelo banco de dados, ou, caso haja interrupção por algum motivo, seja invalidada (ou desfeita) no banco de dados, restaurando todos os dados aos valores que eles apresentavam antes da transação ser iniciada. Veremos mais detalhes sobre esse processo em breve. Outro aspecto que o sistema gerenciador de banco de dados deve garantir é que diversas transações iniciadas em tempos diferentes por vários usuários possam ser corretamente sincronizadas. Imagine que três transações de débito de uma mesma conta sejam iniciadas simul- taneamente. A conta possui, no momento inicial, R$ 100,00 de saldo e cada transação solicita um débito de R$ 50,00. Isoladamente, se cada uma delas verificar o saldo disponível na conta, iria parecer que temos saldo suficiente para um débito de R$ 50,00. Porém, se os três débitos prosseguissem, possuiríamos ao final um saldo negativo de R$ 50,00, Linguagem hospedeira é uma linguagem procedural, de uso geral, utilizada pelo programador para validação, transformação e manipulação dos dados obtidos por meio da linguagem SQL. 1 Gerenciamento de transações 57 pois teríamos transferido R$ 150,00 da conta de origem para liquidar as transações de débito. Isso demonstra que não só uma transação deve ter sua unidade mantida, mas que a sincronização dentre diversas transações precisa ser gerenciada para que uma transação não se inicie antes que a outra, que já trabalha sobre os mesmos dados, seja concluída. Esse controle é definido como controle de concorrência. Enquanto as diversas transações que fazem somente leitura de porções do banco de dados estiverem sendo executadas, não teremos potencialmente nenhum risco de perda de integridade nas informa- ções recuperadas; porém, assim que uma das transações concorrentes executar pelo menos uma atualização no banco de dados, o restante das transações que depende desse conteúdo pode ter seus resultados comprometidos. As operações sobre um banco de dados são caracterizadas basica- mente em dois tipos (Quadro 1). Quadro 1 Operações sobre um banco de dados Read (x) Operação que transfere o conteúdo de um item X do banco de dados para uma área de memória e, então, disponibiliza esse conteúdo em uma variável de programa. Write (x) Operação que transfere o conteúdo de uma variável contida em uma área de memória para o banco de dados, persistindo esse valor no ban- co de dados. Fonte: Elaborado pelo autor. Caso uma determinada sequência de operações de leitura e de gravação seja executada sem o devido controle de transações, po- demos ter falhas, como: atualização perdida; leitura suja; resumo incorreto; e leitura não repetitiva. Vejamos cada uma dessas possí- veis falhas. • Atualização perdida: situação que surge quando uma tran- sação atualiza um valor no banco de dados, mas essa atuali- zação é sobrepostapor outra concorrente, antes mesmo que todo o processo de atualização da primeira transação tenha sido encerrada. O Guia de Controle de Versão de Linha e Bloqueio de Transações mostra como o SQL-Server implementa os controles de concorrência no nível de linha, propiciando meios para um comparti- lhamento de dados com menor risco de conflitos de concorrência. Traz, ainda, uma visão prática de como a teoria estuda- da é implementada em um produto de ampla utilização no mercado. Disponível em: https:// docs.microsoft.com/pt-br/ sql/relational-databases/ sql-server-transaction-locking- and-row-versioning- guide?view=sql-server-ver15. Acesso em: 27 nov. 2020. Vídeo https://docs.microsoft.com/pt-br/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/sql-server-transaction-locking-and-row-versioning-guide?view=sql-server-ver15 58 Banco de Dados II Exemplo: uma transação precisa atualizar a cidade e o estado em que reside uma pessoa para Curitiba e Paraná, respectivamente. Após ter atualizado o nome da cida- de e estar se preparando para fazer o mesmo com o nome do estado, outra transação concorrente é iniciada para atualizar o nome do estado para São Paulo e é finalizada. Porém, logo em seguida, a primeira transação prossegue e atualiza o conteúdo do nome do estado para Paraná. Veremos, então, que a primeira atualização feita para São Paulo foi perdida. • Leitura suja: situação em que um conteúdo de um item do banco de dados é lido enquanto toda a transação ainda não foi completada, entregando a quem solicitou os dados uma infor- mação transitória falsa. Exemplo: uma transação foi construída para fazer a transferência de um valor de uma conta-corrente para outra. Em paralelo, temos outra transação iniciada para somar o saldo de todas as contas-correntes dessa agência. Assim que a conta- -corrente doadora do valor da transferência teve seu saldo subtraído, mas antes que a receptora tenha seu saldo acrescido, a transação que realiza a soma dos saldos é executada. Ela irá encontrar a conta-corrente doadora com, por exemplo, R$ 100,00 a menos, porém não encontrará a conta receptora com um crédito de R$ 100,00, pois esse valor terá sido simplesmente extraviado para o processo de somatório. • Resumo incorreto: situação em que vários registros que te- rão seus dados agrupados para gerar um novo item de dados estão em processo de atualização e ainda não tiveram seus valores propagados para o item agregador. Exemplo: um contrato possui 12 parcelas e um valor principal. Uma atualização do valor das parcelas é iniciada, aplicando um índice de reajuste de 10% a cada parcela. Porém, somente após todas as parcelas terem sido atualizadas, o valor total do con- trato será também corrigido. Se durante a atualização outra transação for iniciada para somar os valores de parcelas e apresentá-los em um relatório, pode ser que se encontre um valor total do contrato divergente do valor da somatória das parcelas. Gerenciamento de transações 59 • Leitura não repetitiva: momento em que duas execuções con- secutivas de leitura de um mesmo conjunto de dados apresentam valores diferentes, visto que, entre uma e outra leitura, algum ou- tro processo realizou a atualização dos dados a ser utilizados. Exemplo: um plano de saúde obtém os dados do titular e de seus dependentes para calcular o valor total do carnê a ser emitido. Após ter descoberto que o titular tem três dependentes e, então, gerado um valor X para o carnê, o sistema volta a realizar a leitura dos nomes dos dependentes para incluí-los no próprio carnê; no entanto, encontra somente dois dependentes, pois outra transação disparada em paralelo acabou excluindo um dos dependentes daquele plano. Essas situações citadas acima podem eventualmente se combinar e gerar ainda novas situações, em que obviamente serão identificadas inconsistências transitórias no banco de dados. O fato de elas serem transitórias não diminui o impacto gerado para os processos de negó- cio, uma vez que, como foi exemplificado, como poderemos justificar para um cliente que estamos cobrando o valor de um carnê relativo a três dependentes, se ao imprimir o carnê aparecem somente dois? Parecerá que nosso processo de emissão de carnês realmente possui um erro, e não que se trata de uma informação transitória. Pior ainda seria o efeito de gerá-lo novamente dez minutos mais tarde e ver que agora o valor é menor, já que realmente só dois dependentes foram encontrados. Como explicar que, ao emitir duas vezes o mesmo carnê, obtemos diferentes valores de cobrança? 3.2 Propriedades de uma transação Vídeo Uma transação, quando observada, independentemente da comple- xidade ou do número e do tipo de operações que realiza, deve assegu- rar que quatro propriedades sejam reconhecidas. Essas propriedades irão assegurar que a transação seja capaz de manter a integridade do banco de dados, tanto de modo transitório quanto definitivo. Assim, essas quatro propriedades são reconhecidas pela sigla ACID, em que cada uma das letras indica o nome de uma propriedade. 60 Banco de Dados II Quadro 2 Propriedades de uma transação A Atomicidade C Consistência I Isolamento D Durabilidade Fonte: Elaborado pelo autor. A propriedade de atomicidade de uma transação define que ou todas as operações de uma transação são refletidas no banco de dados ou nenhuma será. Desse modo, teremos dois estados em que poderemos encontrar um conjunto de dados manipulado por uma transação: antes da atualização e depois da atualização. O tempo em que esse conjunto de dados estiver sendo atualizado, passando por transformações sequenciais, um após o outro, será um momen- to em que esses dados não estarão visíveis para mais ninguém, es- tando totalmente isolados em todo o transcorrer da transação. Assim, logo antes de a transação iniciar, temos acesso aos dados em um estado X e, logo após ela terminar, encontraremos os dados em um estado Y. Caso alguma falha ocorra durante essa atualiza- ção, ela será invalidada, em qualquer ponto onde se encontre, seja no seu começo, meio ou fim, e todos os dados serão retornados ao estado X, logo antes de ela iniciar. Com isso, temos a opção de não voltar a executar a mesma transação, imaginando que os dados nunca deixaram seu estado X, ou voltar a executá-la, usando como referência o estado X para, novamente, tentar fazer com que os da- dos atinjam o estado Y. Esse controle de validação, invalidação e repetição de transações após falhas é realizado automaticamente por um componente do sistema gerenciador do banco de dados, que é o componente de controle de concorrência e subsistema de recuperação e se baseia no escopo de cada transação, o qual, por sua vez, é definido por comandos SQL que determinam os pontos de começo e fim de cada transação. Gerenciamento de transações 61 Figura 1 Componentes do sistema gerenciador de banco de dados COMANDOS DDL Compilador DDL Gerenciamento dos Dados Armazenados COMANDOS PRIVILEGIADOS PESQUISA INTERATIVA Compilador de Pesquisa COMANDOS DDL Compilador DDL Controle de Concorrência/Backup/ Subsistema de Recuperação TRANSAÇÕES COMPILADAS (CUSTOMIZADAS) Compilador da linguagem hospedeira PROGRAMAS DE APLICAÇÃO Catálogo do Sistema/ Dicionário de Dados execução execução D A B E C Usuários casuais Programadoresde aplicação Usuários parametrizáveisEquipe DBA BANCO DE DADOS ARMAZENADO Pré-compilador Processador de Banco de Dados em tempo de Execução (runtime) Fonte: Elmasri; Navathe, 2006, p. 26. A propriedade de consistência de uma transação define que, se ana- lisarmos o estado do banco de dados antes de uma transação e então fizermos, após ela ter sido finalizada, uma nova análise de seu estado, deveremos assegurar que nesses dois estados teremos a consistência do banco de dados garantida. Se, por exemplo, tínhamos antes de uma transação uma conta- -corrente com um saldo de R$ 100,00 e durante a transação recebe- mos um crédito de R$ 50,00, teremos que encontrar obrigatoriamente o banco de dados, em seu estado final, apresentando a conta com um 62 Banco de Dados II saldo de R$ 150,00. Nenhum dinheiro pode ser criado ou destruído dentro do processo sem que uma operação de crédito ou de débito tenha sido realmente executada. Se somente R$ 50,00 foram somados à conta, então não haveria como ela apresentar outro saldo que não fosse o de R$ 150,00. Esse seria o resultado consistente esperado ao final da transação, pois ela não permitiu que nenhuma outra interfe- rência externa ocorresse. Segundo Silberschatz, Korth e Sudarshan (2012), garantir a consis- tência para uma transação individual é responsabilidade do programa- dor de aplicação que codifica a transação. Se ele definir corretamente os pontos de início e fim da transação, utilizando os comandos SQL de begin transaction e commit e até eventualmente rollback, a consistên- cia estará então assegurada. A propriedade de isolamento de uma transação define que, embo- ra diversas transações possam ser executadas de modo concorrente, cada uma delas deve ter a sensação de que sua execução só se iniciou após o término da transação anterior e de que ela está sendo executa- da em modo isolado, e não em concorrente. Essa sensação de isolamento não implica que realmente ele acon- teça. Caso fosse necessário prover um isolamento real, teríamos que optar por uma serialização de transações, ou seja, somente uma transação seria executada de cada vez, fazendo com que as demais tivessem que aguardar seu término antes de iniciar. Isso geraria uma perda significativa de performance. Justamente por esse motivo, algu- mas técnicas foram desenvolvidas para que as transações possam ser executadas concorrentemente, mas gerando o isolamento necessário ao correto funcionamento. Essa propriedade, em conjunto com as pro- priedades de consistência e de atomicidade, garante a consistência glo- bal do banco de dados. O módulo de controle de concorrência provido pelo sistema ge- renciador de banco de dados é, mais uma vez, o responsável por exe- cutar os procedimentos que garantam a sensação de isolamento de transações, mesmo que propicie uma real concorrência entre elas. A propriedade de durabilidade de uma transação define que, de- pois de terminada, seus resultados devem ser garantidos no novo es- tado para o qual o banco de dados foi levado. Se, por exemplo, nossa Gerenciamento de transações 63 transação se iniciou com uma conta-corrente tendo um saldo de R$ 100,00 e foi realizado um crédito de R$ 50,00, então, ao terminar, o saldo deverá ser mantido com o valor de R$ 150,00, inclusive se alguma falha vier a acontecer com o banco de dados após a conclusão. A fim de que a durabilidade da transação possa ser assegurada, to- dos os dados alterados no escopo da transação precisam ser grava- dos em disco antes da sinalização do seu término. Logo, nenhum dado pode ser mantido só em memória até o final da transação, pois, caso isso aconteça e a transação venha a ter alguma falha, os dados não estariam preservados em disco e seriam perdidos. Outra operação que deve ser garantida pelo sistema gerenciador do banco de dados, no subsistema de recuperação, diz respeito a gerar, nos arquivos de log de atualização, todos os registros que permitam refazer a transação após ela ter sido terminada, para que, no caso de alguma falha ocorrer, implique na ativação automática do subsistema de recuperação. Se os logs de atualização estivessem somente em me- mória, e não gravados em disco, correríamos o risco de, ao reiniciar o banco de dados, não possuirmos meios para aplicar as imagens de atualização dessa última transação dita como completada. Todas essas características desejáveis em uma transação se aplicam durante os estados da transação. Como a transação é uma unidade de processamento que deve ter começo, meio e fim nitidamente defini- dos, é de se imaginar que durante o seu transcorrer possamos iden- tificar vários intervalos distintos, os quais são definidos como estados da transação. Dessa maneira, temos um total de cinco estados em uma transação, que são: ativa; parcialmente completada; completada; falha; e abortada. Esses estados servem como referência para que o sistema geren- ciador de banco de dados possa identificar em que fase do processo aquela transação em especial se encontra para, então, prover ati- vidades complementares de gerenciamento da transação, as quais precisam ser agregadas antes, durante e após a execução de cada instrução SQL contida na própria transação. Esses controles adicio- nais são os que se certificarão de que as propriedades ACID sejam garantidas durante a execução da transação isoladamente ou de modo concorrente a outras. 64 Banco de Dados II Figura 2 Diagrama dos estados de uma transação ativa abortada confirmada falha parcialmente confirmada Fonte: Silberschatz; Korth; Sudarshan, 2012, p. 412. O status de transação ativa é aquele em que a transação se encon- tra logo após ter se iniciado, permanecendo nele enquanto os diversos processos internos (instruções SQL) que ela executa vão se sucedendo, um após o outro. Podemos ter transações com um único ou com múl- tiplos processos internos, chamadas de transações curtas e transações longas, respectivamente. Cada instrução SQL executada em uma tran- sação é precedida de uma preparação (atividades internas do SGBD) e também de outras atividades de finalização da instrução, permitindo que a próxima instrução se siga. Após executar sua última instrução, a transação entra no esta- do de parcialmente completada. Isso significa que não existe mais nenhuma instrução SQL pendente para ser executada e que, então, estamos prontos para realizar o encerramento da transação. No en- tanto, como vimos, a característica de durabilidade exige que, para uma transação ser definitivamente completada, temos que execu- tar todas as tarefas internas do banco de dados, como gravar os dados que estão em memória no disco, gerar os registros de log Gerenciamento de transações 65 de atualização para que eventualmente ela possa ser reprocessa- da, entre outros exemplos. Essas são tarefas que não pertencem propriamente à transação criada pelo programador, mas que são agregadas pelo sistema gerenciador do banco de dados. São justamente essas tarefas extras, executadas após o término das instruções SQL, que podem gerar algum tipo de falha, fazen- do com que uma transação parcialmente completada não possa ir para o estado de confirmada e entre no estado de falha. Em caso de sucesso dos procedimentos complementares executados após o término das instruções SQL, e somente nesse caso, a transação teria entrado realmente no estado de confirmada. Outro motivo para uma transação ter entrado em estado de falha seria se algum erro de sistema, de hardware ou até de falta de ener- gia impedisse que todas as instruções SQL fossem executadas até seu final. Nesse contexto, não teríamos atendido aos requisitos da característica de atomicidade de uma transação, logo seria necessário realizar um tratamento para a falha detectada. Independentemente do tipo de falha detectada, as característi- cas de atomicidade e consistência exigem que tudo o que foi feito até aquele momento seja desfeito para que o banco de dados seja restaurado até uma situaçãode estabilidade, na qual ele se encon- trava antes de iniciar a transação. Assim, depois de ir para o estado de falha, a transação começa a sofrer um processo de recuperação que, após terminado, a deixará no estado de abortada, ou seja, can- celada. Dessa maneira, o sistema gerenciador de banco de dados identificará a transação abortada e avaliará se ela pode ser reexecu- tada ou se terá que encerrar definitivamente o seu processamento, interrompendo também o programa que a executava. O fato impor- tante é que a estabilidade do banco de dados estará assegurada de um modo ou de outro. Dentre os tipos de falhas que podem levar uma transação do seu estado de falha para o estado de abortada sendo, portanto, desfeita, estão as seguintes: 66 Banco de Dados II Quadro 3 Tipos de falhas Tipo de falha Exemplo O que pode ser feito? Falha prevista em código. Uma transferência entre contas en- contra uma conta inativa. Programador executa uma instru- ção rollback, desfaz a transferência e prossegue. Falha não prevista em código. Ao calcular o valor de uma parcela, o total é dividido por zero, pois a quan- tidade de parcelas está zerada. SGBD desfaz a transação e in- terrompe o processo. Falha do sistema operacional que não afeta o banco de dados. Falta de memória, travamento de um processo. SGBD desfaz a transação e interrompe o processo. Falha que afeta o banco de dados. Um disco apresenta erro de grava- ção irrecuperável. SGBD interrompe o processamen- to e requer intervenção externa. Falha operacional. Um processo é cancelado pelo ope- rador. SGBD desfaz a transação e requer intervenção externa. Fonte: Elaborado pelo autor. As situações de falhas descritas podem ocorrer de modo isola- do, em uma única transação, ou de modo simultâneo, quando várias transações são executadas em paralelo. Para que várias transações possam ser executadas concorrentemente, de modo consistente, al- guns mecanismos foram criados na linguagem SQL. 3.3 Suporte a transações no SQL Vídeo O controle do início e término de uma transação dentro da lingua- gem SQL é feito por meio dos comandos que pertencem ao grupo de instruções TCL, ou transaction control language. Temos, nesse grupo, os comandos commit, rollback e eventualmente o savepoint. Esses comandos não executam propriamente uma instrução para consulta ou atualização no banco de dados, mas delimitam e comandam ações para o sistema gerenciador saber onde o programador entende que suas unidades de processamento começam e terminam. O início de uma transação se dá sempre quando um comando SQL de recuperação ou atualização de dados é submetido ao ban- co de dados e termina quando uma instrução commit, rollback ou savepoint é executada. Portanto, o programador deve instruir ao sistema gerenciador sobre quais comandos SQL devem ser agru- pados, desde o primeiro comando executado até o momento em Gerenciamento de transações 67 que deseje criar um ponto de recuperação (savepoint) ou confir- mar definitivamente todas as atualizações que realizou no banco de dados (commit). Caso o programador entenda que, por algum motivo, sua transa- ção precisa ser desfeita por completo ou simplesmente retornada ao último ponto de recuperação disponível (no caso de transações aninhadas), ele poderá executar o comando rollback para progra- maticamente solicitar que o sistema gerenciador de banco de dados desfaça as atualizações feitas e deixe novamente o banco de dados em uma situação estável. Esse mesmo procedimento de rollback pode ser acionado automaticamente pelo sistema gerenciador de banco de dados quando alguma falha for detectada no decorrer da transação. Criar transações muito longas pode ter um efeito indesejável de reter muitos dados por bastante tempo sem que outros progra- mas possam acessá-los de modo concorrente. Por outro lado, criar transações muito curtas pode fazer com que não existam dados suficientemente estáveis no decorrer da transação, pois, sendo li- berados muito cedo, eles podem ser atualizados por outras tran- sações. Desse modo, a transação ideal deve ter o controle sobre uma quantidade mínima de dados, porém sem comprometer a con- sistência do processo. Já quando falamos em bloqueio de recursos por uma transação, temos dois tipos de recursos envolvidos: os dados que são lidos e os que são atualizados no transcorrer da transação. Pode parecer es- tranho termos que bloquear os dados que somente são lidos e não atualizados, no entanto, se isso não for feito, podemos ter dois tipos de falhas comuns, que são a leitura suja e a não repetitiva. Sendo também necessário o bloqueio de dados que são somente lidos, os sistemas gerenciadores de bancos de dados passam a ofe- recer várias modalidades de bloqueio para otimizar esse processo, fazendo com que uma leitura possa ser feita em modo exclusivo (após lido, o dado não pode mais ser lido por ninguém) ou em modo compartilhado (após a leitura, ele não pode ser atualizado por mais ninguém, mas pode ser lido por outras transações). Esses bloqueios são definidos, respectivamente, como bloqueio pessimístico e blo- queio otimístico. 68 Banco de Dados II O bloqueio pessimístico traz naturalmente uma sensação de se- rialização de transações, visto que, a partir do momento em que um dado é utilizado em uma transação, mesmo que para leitura, todas as demais transações devem aguardar que essa transação libere aquele recurso. Essa é a forma de acesso que traz maior impacto negativo para a performance de execução de transações simultâneas no banco de dados. Esses bloqueios são também denominados de locks, apresentando então as características de um shared lock (slock), quando ele não é exclusivo, e as de um xlock, que ocorre quando ele é exclusivo. Ana- lisando essas duas transações concorrentes, podemos ter a seguinte combinação de situações: Quadro 4 Liberação de acessos de lock a duas diferentes transações Transação A Transação B Solicita slock Solicita xlock Não realizou nenhum lock até o momento. Slock concedido. Xlock concedido. Slock já concedido. Slock concedido. Xlock negado. Aguardará liberação. Xlock já concedido. Slock negado. Aguardará liberação. Slock negado. Aguardará liberação. Fonte: Elaborado pelo autor. Outro detalhe importante a ser considerado é que, quando fa- lamos em bloquear um dado, precisamos lembrar que esse está, na verdade, armazenado em uma página do banco de dados (nor- malmente algo em torno de 4 Kbytes) e que talvez o sistema geren- ciador de banco de dados acabe por bloquear toda a página e os demais itens que nem estão sendo referenciados nessa transação. Ou seja, o bloqueio de leitura de um de dado também bloqueia outros 4 Kbytes de dados da mesma tabela ou até de outras si- multaneamente, propagando um efeito de retenção de recursos do banco de dados. Para evitar esse efeito ainda mais negativo, al- guns sistemas gerenciadores de bancos de dados podem oferecer bloqueio de dados no nível de linhas, e não no de páginas, fazendo com que somente uma linha dentro da página de 4 Kbytes seja blo- queada isoladamente. Gerenciamento de transações 69 3.4 Técnicas de controle de concorrência Vídeo Segundo Elmasri e Navathe (2006), as diversas técnicas de controle de concorrência de transações são necessárias para garantir o isola- mento das transações executadas em modo concorrente, e quase todas elas implicam em serialização das transações envolvidas. Grande parte dos sistemas gerenciadores de bancos de dados comerciais se utiliza de protocolos (ou regras) que implementam bloqueios para garantir essa serialização. Outros usam protocolos baseados em timestamps (marcas de tempo) para ordenar e sequenciar as transações, criando também como resultado uma serialização das mesmas. A primeira técnica que veremos é denominada bloqueio em duas fa- ses. Ao falarmos em bloqueio, precisamos lembrar que esse conceito está associado à liberação de permissões para acessar ou alterar um dado em função do estadode bloqueio anterior no qual ele se encon- trava. A técnica mais simples para controle de bloqueio é chamada de bloqueio binário, no qual, como o próprio nome diz, temos somente dois estados possíveis associados a um dado: livre ou bloqueado. Isso significa que, para qualquer operação que se deseje fazer, temos so- mente a opção de solicitar o bloqueio completo daquele dado. Por ser um processo muito simples, ele acaba não servindo para situações prá- ticas e, portanto, não é utilizado na prática. A implementação do bloqueio binário exige poucos recursos do sis- tema gerenciador de banco de dados, pois precisamos somente de uma área de controle, na qual possamos informar três elementos: o nome do dado, a indicação lock e a transação que está detendo o bloqueio. Desse modo, qualquer outra transação que solicite acesso a esse dado pode encontrá-lo já bloqueado pela transação X. Porém, se a própria transação X solicitar o acesso novamente, o sistema gerenciador de bancos de dados percebe que ela mesma detém o bloqueio e permite o acesso. Todas as demais transações que desejem acesso a esse dado entram em um fila, onde aguardam a liberação pela transação X. Logo que for liberado, o dado é oferecido à primeira transação que aguarda na fila, e assim sucessivamente. Porém, como dissemos, o bloqueio binário é muito restritivo. Com o intuito de prover um mecanismo mais aprimorado de bloqueios, foi de- finido um bloqueio que pode trabalhar com três estados diferentes para 70 Banco de Dados II um dado: liberado, bloqueado em modo compartilhado e bloqueado em modo exclusivo. Esses três estados são conhecidos também como: unlocked, read_locked e write_locked, respectivamente. Esse mecanismo de três estados tem como principal vantagem o fato de não bloquear o acesso simultâneo de várias transações que desejem somente realizar a leitura de um item de dado. Se, por exemplo, uma transação já iniciou um bloqueio do tipo read_locked e outra transação também solicitar esse bloqueio, ela terá assegurado o acesso ao mesmo dado. No processo de bloqueio binário, essa opção não existe, fazendo automaticamente com que a segunda transação entre em uma fila de espera. Para implementar no sistema gerenciador de banco de dados esse novo tipo de controle, precisamos não de três, mas de quatro cam- pos distintos em nossa área de controle: nome do dado, tipo de blo- queio, lista de transações com bloqueio de leitura e nome da transação com bloqueio de gravação. Quando o campo de tipo de bloqueio for read_locked, temos no campo de lista de transações o nome de todas as transações que compartilham a leitura desse dado. Já quando o campo for write_locked, temos o nome da transação que bloqueia em modo exclusivo o dado. Conhecendo todos esses requisitos de controle, podemos passar efetivamente à descrição do processo de bloqueio em duas fases. Se- gundo Elmasri e Navathe (2006), uma transação segue o protocolo de bloqueio em duas fases se todas as operações de bloqueio precederem a primeira operação de desbloqueio. Temos, então, a primeira fase, chamada de fase de expansão ou crescimento, na qual um ou mais pe- didos de bloqueio podem ser assegurados, mas não uma operação de desbloqueio. Há também uma segunda fase, denominada encolhimen- to, em que uma ou mais operações de desbloqueio podem ser assegu- radas, porém não uma operação de bloqueio. Se a conversão de bloqueios for possível (mudando de read_lock para write_lock e vice-versa), teremos que respeitar a regra de que a promoção de um bloqueio (de read_lock para write_lock) deve obriga- toriamente acontecer na fase de expansão, e que o rebaixamento de bloqueio (de write_lock para read_lock) deve ser feito na fase de enco- lhimento. Assim, pode ser provado que, se uma transação seguir as regras do bloqueio em duas fases, haverá sempre a garantia de que a serialização pode produzir o resultado desejado na manutenção do iso- lamento de transações. No entanto, se estudada em maiores detalhes, Gerenciamento de transações 71 veremos que a técnica de bloqueio em duas fases pode ser especiali- zada em quatro tipos, cada um com suas vantagens e desvantagens: básico, conservador, estrito e rigoroso. Todas essas técnicas de bloqueio trazem naturalmente alguma desvan- tagem e podem gerar problemas típicos, que precisam ser tratados pelo sistema gerenciador de banco de dados. O primeiro problema clássico en- contrado é o deadlock. Um deadlock (impasse) é descrito como uma situa- ção de espera indefinida, em que uma transação A está na fila de espera, aguardando que uma transação B libere um item de dado X, enquanto a transação B também se encontra em uma fila de espera pela transação A, até que essa libere um item de dado Y. Como uma está esperando pela outra, ambas não prosseguem e ficam eternamente aguardando recursos cruzados. Nesse caso, o que o sistema gerenciador de banco de dados faz é interromper a transação B, reiniciando-a automaticamente. O fato de rei- niciá-la dará tempo para que a transação A prossiga até seu final. Assim, quando a transação B solicitar os recursos retidos pela transação A (que já terá sido completada), eles estarão liberados. Algumas técnicas podem também ser implementadas para evitar que o deadlock se crie; uma delas define que os locks de todos os recursos que a transação irá utilizar sejam assegurados logo no início da transação, e não durante sua execução. Outro problema típico que pode ocorrer por meio dos controles de concorrência baseados em bloqueio é conhecido como starvation (ina- nição). Caso o algoritmo que define as filas de espera por um recur- so não seja apropriadamente definido, podemos ter uma situação em que uma transação com baixa prioridade acabe por ficar aguardando indefinidamente em uma fila, enquanto todas as demais transações prosseguem normalmente. Para atuar sobre esse tipo de problema, podemos, por exemplo, definir que a ordem de espera na fila de recur- sos siga o protocolo FIFO (First-in, First-out). Além da técnica de controle de concorrência baseada em bloqueio em duas fases, temos a técnica baseada em ordenação, chamada de timestamp. Um timestamp pode ser produzido pelo sistema gerenciador de banco de dados e associado a cada transação em execução. Ele pode ser um número sequencial (que, por ser finito, teria que ser reinicializado em algum momento) ou uma indicação de data, hora, minuto, segundo e centésimo de segundo. Esse timestamp será utilizado para serialização dos pedidos de read_lock e write_lock, de acordo com algoritmos espe- cíficos. Quando uma transação solicitar um item de dado de modo con- No vídeo Processamento de Transações, publicado por André Santanchè, você confere a parte 1 da aula ministrada por ele. Nela são apresentados todos os conceitos de gerenciamento de tran- sações, com exemplos práticos de processos em que a serialização pode resolver problemas de produção de resultados divergentes, conforme a ordem de execução de duas diferentes transações concorrentes. Disponível em: https://youtu. be/8Wur04WPZRc. Acesso em: 27 nov. 2020. Vídeo https://youtu.be/8Wur04WPZRc https://youtu.be/8Wur04WPZRc 72 Banco de Dados II flitante com outra, fora da sua ordenação natural de serialização, essa transação será cancelada e reiniciada ganhando um outro timestamp. Uma terceira técnica de controle de concorrência é denominada multiversão. Nessa técnica, quando um dado é alterado por uma tran- sação, cria-se uma cópia desse dado com o novo valor, mantendo em memória tanto o item alterado como o não alterado. Caso uma outra transação solicite uma nova alteração do mesmo dado, uma diferente versão do dado também será feita. Isso criará uma complexidade de gerenciamento adicional, pois cada transação executando em paralelo poderá ter como referência um valor diferente do mesmo dado e, em algum momento, todas as versões precisarão ser sincronizadas. A quarta técnica disponível é a técnica intitulada controlede con- corrência de validação ou controle de concorrência otimista. Nas demais técnicas que vimos anteriormente, sempre ao se iniciar uma transação ou ao solicitar acesso a um dado, há uma validação prévia do estado em que ele se encontra em termos de bloqueios já assegurados. Isso gera uma perda de desempenho, uma vez que cada operação de leitu- ra ou gravação deve ser, em todo caso, precedida de uma avaliação de bloqueio. O que a técnica otimista utiliza como base para seu algoritmo é o fato de que, provavelmente, o dado que uma transação está solici- tando terá pouca chance de estar bloqueado por uma outra. Este é o conceito denominado de otimista: apostaremos que não haverá conflitos de concorrência e, caso ele aconteça, trataremos como uma exceção. Assim, a transação se iniciará e irá obter todos os recur- sos que deseja. Caso atualize algum dado obtido, essa atualização não será automaticamente aplicada no banco de dados, ficando somente em memória cache. Ao finalizar a transação, será então verificado se houve alguma violação de serialização; caso isso tenha acontecido, os dados atualizados serão descartados e a transação reiniciada, não ha- vendo, portanto, nenhuma atualização efetiva no banco de dados. Todas essas técnicas, se corretamente aplicadas, podem trazer resul- tados para o tratamento de acesso concorrente aos mesmos recursos do banco de dados. Até aqui exemplificamos as diversas técnicas, levando em consideração o controle de bloqueio e liberação de recursos a nível de dado. Porém, o nível de granularidade 2 de bloqueio pode ser diferente e gerar vários impactos em diversos sistemas gerenciadores de bancos de dados. A granularidade de menor nível seria o bloqueio no nível de dado, ou seja, do valor de uma determinada coluna de uma linha específi- Neste resumo elaborado pelo Centro de Infor- mática da Universidade Federal de Pernambuco (UFPE), você encontrará slides que sintetizam os principais conceitos sobre o gerenciamento de tran- sações e controle de con- corrência. São apresenta- dos alguns exemplos de processos de serialização, demonstrando quando ela é viável e quando não pode ser aplicada. Disponível em: https://www.cin. ufpe.br/~in940/transacoes.pdf. Acesso em: 27 nov. 2020. Leitura O nível de granularidade define a abrangência do bloqueio de recursos que o SGBD poderá realizar. 2 https://www.cin.ufpe.br/~in940/transacoes.pdf https://www.cin.ufpe.br/~in940/transacoes.pdf Gerenciamento de transações 73 ca. Se conseguirmos atuar nesse nível de bloqueio, poderemos ter me- nor nível de conflitos de concorrência e, também, ter bloqueios no nível de registros ou linhas de uma tabela. Nesse caso, mesmo que tenha- mos solicitado o acesso a somente uma coluna de uma linha, tomando como exemplo o código de matrícula de um aluno, teremos bloqueado todos os dados daquele estudante para qualquer outra transação. Isso pode ser ainda pior se o bloqueio acontecer no nível de um bloco de disco, que pode ter até 4 Kbytes de dados, de um arquivo, de uma ta- bela inteira ou até do banco de dados inteiro. Reconhecer o nível de granularidade de bloqueio pode nos fazer en- tender melhor por que uma transação pode gerar um deadlock, tendo que ser reiniciada, mesmo que, muitas vezes, não esteja concorrendo explicitamente por nenhum recurso igual ao que uma transação anterior esteja utilizando. Desse modo, o bloqueio pode não estar acontecendo no nível de dado, mas sim no nível de linha ou de tabela. CONSIDERAÇÕES FINAIS A habilidade de processar múltiplas transações concorrentemente, tendo todas elas compartilhando um mesmo conjunto de dados, é uma das principais características buscadas quando optamos por utilizar um sistema gerenciador de banco de dados ou até mesmo quando modela- mos e projetamos um banco de dados. Sem essa habilidade, pouco adiantaria termos um repositório de da- dos a compartilhar, uma vez que perderíamos a capacidade de realmente fazer esse compartilhamento de dados entre aplicações e usuários. Com isso em mente, os fornecedores de sistemas gerenciadores de bancos de dados têm investido constantemente em aprimorar seus algoritmos de gerenciamento de concorrência. Dessa maneira, eles buscam o menor grau de granularidade para bloqueio, os melhores processos de serializa- ção e as mais avançadas técnicas de recuperação de conflitos. A competitividade entre diferentes fornecedores de sistemas ge- renciadores de bancos de dados tem feito com que o maior beneficia- do, no final, seja o próprio desenvolvedor de sistemas, que cada vez mais conta com recursos para fazer com que seus programas possam ter acesso concorrente a um banco de dados compartilhado, com o menor grau de impacto. Assim, todo o trabalho que seria gerenciado pelo programador passa a ser provido pelos sistemas gerenciadores de bancos de dados, os quais, pela evolução contínua, oferecem mais e melhores recursos. 74 Banco de Dados II ATIVIDADES 1. Justifique por que o controle de transações é essencial para o compartilhamento de dados por um banco de dados. 2. Exemplifique uma situação em que uma transação, já tendo completado todas as suas operações internas, ainda conseguiria gerar algum tipo de erro que pudesse afetar a característica de durabilidade da transação. 3. Podemos aplicar o rollback para desfazer uma transação em duas situações distintas, uma controlada pelo programador e outra pelo sistema gerenciador de banco de dados. Quais são essas situações? 4. Explique como acontece um deadlock entre duas ou mais transações e como o sistema resolve essa situação de modo a permitir que o processamento continue. REFERÊNCIAS DATE, C. J. Introdução a sistemas de banco de dados. Rio de Janeiro: Elsevier, 2004. ELMASRI, R.; NAVATHE, S. Sistemas de banco de dados. 4. ed. São Paulo: Pearson Addison Wesley, 2006. SILBERSCHATZ, A.; KORTH; H. F.; SUDARSHAN, S. Sistema de banco de dados. 6. ed. Rio de Janeiro: Elsevier, 2012. Técnicas de recuperação em banco de dados 75 4 Técnicas de recuperação em banco de dados A utilização de uma estrutura de bancos de dados como o ele- mento central de compartilhamento de dados para um ou mais sistemas de informação tem sido, cada vez mais, a estratégia utili- zada por quem define as arquiteturas de sistemas modernos, se- jam eles de pequeno, médio ou grande porte. Tanto as aplicações pessoais para utilização em dispositivos móveis quanto os grandes sistemas corporativos têm hoje forte dependência de dados obti- dos de bancos de dados. Se por um lado essa estratégia agrega inúmeros benefícios pelo compartilhamento dos dados, por outro, ela expõe todos esses sis- temas de informação a um mesmo risco: à perda momentânea ou definitiva de uma ou mais porções desse mesmo banco de dados. A mesma indisponibilidade que antes poderia afetar somente um sistema de informação, agora afeta inúmeros sistemas simul- taneamente. A recuperação de um banco de dados que, anterior- mente, poderia depender somente de uma iniciativa isolada de um sistema – o qual, então, reprocessaria os dados atualizados desde a última cópia de segurança feita – agora não mais é possível, pois as transações de diversas aplicações passaram a alterar, incluir e excluir dados concorrentemente no mesmo banco de dados. Esse cenário cria, assim, um novo e complexo desafio: o de assegurar a alta disponibilidade dos dados do banco de dados, evitando que sejam corrompidos ou perdidos e recuperando, no menor prazo possível, esse mesmo banco de dados, de modo que o traz à situação de normalidade após a ocorrência de um evento de falha que comprometa esses dados. Veremos, neste capítulo, quais são os elementos e recursos que podem nos conduzir à superação desse desafio. 76 Banco de Dados II 4.1 Classificação das falhas Vídeo Em um ambiente de tecnologia da informação, diversos elemen- tos são combinados, provendo uma arquitetura final, a qual servirá para a implementação não só de um banco de dados, masde todo um sistema de informação. Temos, nesses ambientes, a conjugação de diferentes sistemas ope- racionais, sistemas de gerenciamento de banco de dados, programas, softwares de gestão empresarial, infraestrutura de comunicação e in- terconectividade, camadas de segurança, dispositivos de acesso etc. Dessa maneira, cada um desses elementos passa a ser um possível foco de ocorrência de incidentes, que podem ser causados por falhas isoladas ou conjuntas. Um incidente é, por definição, uma interrupção ou comprometimento da qualidade de um serviço de TI, e os serviços de TI são os facilitadores de operação dos processos de negócios ofe- recidos pela própria TI. Logo, qualquer interrupção não programada da disponibilidade de um servidor de banco de dados agregado, por exemplo, a um serviço de controle de acessos em uma empresa, pode- ria causar impactos diretos no dia a dia dessa organização. Para exemplificar, funcionários que não pudessem entrar na em- presa no início do expediente, por conta de o sistema de liberação de acesso estar sem capacidade de verificar suas permissões no banco de dados, acabariam por comprometer a própria operação da empresa, bem como os produtos que ela produz ou os serviços que ela presta ao mercado. Procedimentos de contingência criados para contornar esse in- cidente poderiam até estar disponíveis, porém acarretariam custos adicionais, consumo de tempo, atrasos na liberação de acessos dos funcionários, horas extras para tratamento de dados coletados em planilhas de controle e tantos outros desconfortos. Do ponto de vista das melhores práticas de gerenciamento de serviços de TI, todo o setor de TI deve estar focado em evitar que essas indisponibilidades venham a ocorrer, pois as áreas de negócio dependem agora fortemente da disponibilidade dos serviços de TI. Entre as falhas possíveis, podemos identificar basicamente dois tipos, que são: Técnicas de recuperação em banco de dados 77 • falhas não catastróficas; • falhas catastróficas. As falhas não catastróficas permitem que um processo de recu- peração automático e rápido possa ser aplicado pelo próprio siste- ma operacional ou pelo sistema gerenciador de banco de dados, sem qualquer intervenção externa. Já as falhas catastróficas são aquelas que precisam de uma intervenção pessoal para que possam ser re- cuperadas, após a análise do que causou a falha, das alternativas de recuperação, dos recursos disponíveis para a recuperação, do tempo envolvido na recuperação, dos planos de contingência, dentre outros fatores, sendo, portanto, muito mais complexas para serem tratadas. Independentemente do tipo de falha que venha a ocorrer, temos que prover, por meio de mecanismos implementados pelo sistema gerenciador de banco de dados, algum meio para que o banco de dados seja restaurado ao ponto de dar estabilidade anterior ao fato gerador dessa falha. Esse é o objetivo das técnicas de recuperação que veremos a seguir. Segundo Silberschatz, Korth e Sudarshan (2012, p. 459), “o tipo mais simples de falha é aquela que não resulta na perda de informações no sistema. As falhas que são mais difíceis de tratar são aquelas que resul- tam em perda de informação”. Assim, essa é outra maneira de definir aquelas que são não catastróficas e catastróficas. A catástrofe significa, então, a perda das informações ou de dados. Como falhas não catastróficas, Silberschatz, Korth e Sudarshan (2012) citam, primeiramente, as falhas de transação, ou seja, aquelas que acontecem enquanto uma transação está sendo processada pelo siste- ma gerenciador de banco de dados e não permitem que essa transação se complete. Esse tipo de falha pode ter duas origens distintas: erro lógico ou erro do sistema. Um erro lógico significa que, durante o acesso aos dados ou ao seu processamento, uma condição de falha é detectada pelo programa, quer seja porque um dado tem um valor indevido, quer seja porque um recurso não é identificado ou, até mesmo, um limite qualquer de recursos é encontrado. Podemos imaginar uma situação em que um programa está execu- tando uma transação para calcular uma determinada média, dividindo um valor X por um outro valor Y. Porém, devido a alguma inconsistên- 78 Banco de Dados II cia de dados, o valor de Y é zero. Ao dividir o valor X por zero, é gerado um erro lógico de estouro no processamento da divisão (não é possível dividir um valor por zero, como a matemática nos ensina). Com isso, a transação de cálculo da média tem que ser interrompida e retomada. Já em relação a um erro de sistema, podemos imaginar uma situa- ção em que um deadlock é gerado entre duas transações. Isto é, a tran- sação A solicita um recurso que está bloqueado pela transação B, o qual por sua vez já aguarda um recurso bloqueado pela transação A. Nessa situação, a transação causadora do deadlock (transação A) deve ser cancelada e retomada. No entanto, para que a transação possa ser reprocessada futuramente, será necessário restabelecer o estado do banco de dados a uma posição anterior à falha. Dentre as falhas catastróficas, citadas por Silberschatz, Korth e Sudarshan (2012), estão aquelas geradas por falha do sistema opera- cional ou do sistema gerenciador de banco de dados, em que os da- dos do banco não podem ser preservados em estado de estabilidade. Falhas de gravação, leitura ou transferência de blocos de dados entre dispositivos físicos e a memória principal podem ser vistas como situa- ções nas quais um processo de recuperação automática não se aplica. Desse modo, a recuperação dessas falhas catastróficas deve ser realizada por meio de estruturas de recuperação específicas. Se não coletarmos previamente coletado dados que nos permitam restabelecer uma transação, não há maneira efetiva para realizar essa recuperação. Praticamente todos os mecanismos de recuperação se baseiam em logs de atualização (redo logs). Logs são arquivos que mantêm informa- ções sobre as transações e atualizações executadas sobre um banco de dados desde seu último processo de cópia de segurança. Ou seja, eles servem para que possamos restaurar o banco de dados até o último momento de estabilidade conhecido. Quando porções de um banco de dados são corrompidas ou per- didas por um crash de disco (destruição física da superfície do disco), não resta opção senão restaurar uma cópia física do banco de dados (backup) de uma versão estável disponível e, sobre essa versão, aplicar um processo que refaça automaticamente todas as atualizações feitas, por meio de transações que ocorreram nesse banco de dados desde a data do último backup realizado. Técnicas de recuperação em banco de dados 79 Sem esse recurso, seria praticamente impossível recuperar o ban- co de dados ao seu estado de logo antes do crash de disco, pois te- ríamos que solicitar a cada usuário que realizasse de novo todas as atualizações manualmente e, ainda pior, na mesma ordem que foram executadas anteriormente. Os arquivos de log têm, então, os dados para recriar esse cenário de atualizações na exata ordem em que fo- ram executadas, podendo refazê-las. As classificações de falhas catastróficas apresentadas podem, even- tualmente, não ser sempre indicativos rígidos e imutáveis. Um evento de falha no sistema operacional, por exemplo, pode acabar por gerar perda de informações, resultando em uma falha catastrófica em alguns casos, mas pode também não gerar essa perda, sendo então não ca- tastrófico. Sendo assim, nem todas as falhas de sistema operacional podem ser categorizadas como catastróficas. Tudo dependerá do tipo de falha, do componente de sistema operacional afetado, do momento em que ela ocorreu, do estado da transação que estava sendo executa- da e da existência ou não de algum tipo de recurso – como redundância de dados, espelhamento de discos etc. Os sistemas operacionais e os sistemas gerenciadores de bancos de dados relacionais têm, atualmente, recursos modernos que fazem com que poucos eventos de falhas catastróficasacabem por afetar realmen- te a disponibilidade de um banco de dados, deixando-os indisponíveis por longos períodos e impactando nos processos de negócios. A gran- de maioria dos eventos de falhas hoje percebidos se enquadra em si- tuações não catastróficas, podendo passar despercebidos por quase todos os usuários dos sistemas de informação. Muitas vezes, uma pequena lentidão notada em uma transação que sempre teve um desempenho adequado, ou um refresh (recarga) de uma tela, pode significar que um processo de recuperação automáti- ca de uma transação está sendo executado pelo sistema gerenciador de banco de dados de modo que permite aos demais processos ter prosseguimento sem qualquer indisponibilidade real para o usuário do sistema de informação. Como essas situações são causadas, na maioria dos casos, somente em função da concorrência de processos que estão sendo executados naquele instante, podemos voltar a executar a mesma transação em outros momentos, sem qualquer indício de uma falha estar sendo de- tectada e corrigida automaticamente. 80 Banco de Dados II 4.2 Estruturas de recuperação Vídeo Para a recuperação de falhas catastróficas, temos que utilizar al- gum tipo de intervenção manual para restaurar uma cópia de se- gurança (backup) do banco de dados e aplicar as atualizações do redo log. Porém, para a recuperação daquelas não catastróficas, temos, segundo Elmasri e Navathe (2006, p. 439), “duas técnicas principais de recuperação de falhas não-catastróficas de transação: (1) atualização adiada e (2) atualização imediata”. A técnica de atualização adiada pode ser utilizada quando as atua- lizações realizadas no banco de dados são efetivadas em disco – isto é, os dados são gravados em disco – somente no momento em que uma transação é confirmada (commit). Já a técnica de atualização imediata utiliza o conceito de que as atualizações realizadas no banco de dados por comandos SQL já acontecem fisicamente em disco, mesmo antes de a transação ser formalmente efetivada por um comando SQL commit. Porém, para que essas técnicas sejam aplicáveis, temos primeira- mente que conhecer e compreender as estruturas de dados envolvi- das tanto na atualização como na recuperação de dados do banco de dados. Essas estruturas são manipuladas pelo sistema gerenciador de banco de dados em conjunto com o sistema operacional. A primeira estrutura a ser conhecida é a página (ou bloco) de disco. Essa é uma unidade de leitura ou gravação que o sistema operacional define para ser lida ou gravada a cada comando de manipulação de dados que recebe. Quando a atualização de um único item de dado, ou de uma única linha de uma tabela, é solicitada, toda a página em que esse item reside será manipulada. Figura 1 Estrutura de transferência de dados em blocos B A B input (A) output (B) discomemória principal Fonte: Silberschatz; Korth; Sudarshan, 2012, p. 461. Técnicas de recuperação em banco de dados 81 Essas páginas (ou blocos) são, por sua vez, mantidas temporaria- mente em uma estrutura de memória principal (buffers), onde são atualizadas antes de serem devolvidas para que sejam gravadas fisica- mente em disco. Esse processo assegura que o acesso a uma mesma página, quando solicitado por mais de um processo concorrente, possa ser otimizado. Uma coleção de buffers que mantém páginas de dados de um banco de dados é também referenciada como cache do banco de dados. Essa área é gerenciada pelo sistema gerenciador de banco de dados (SGBD) para otimizar sua operação. Quando um item de dados é solicitado por um programa para o SGBD, este primeiro verifica se o item requisitado está disponível em uma das páginas mantidas em cache. Estando lá, esse item de dado é provido ao programa que o requisitou de modo muito mais rápido do que se tivesse que ser acessado em disco. Caso não esteja disponível em cache, cabe ao sistema gerenciador de banco de dados requisitar ao sistema operacional a página onde se encontra esse item, que então deve ser localizada em disco e transferida para a memória principal. Considerando que o espaço de memória cache é limitado, temos que aplicar algum tipo de estratégia de gerenciamento de espaço para que essa nova página, acessada em disco, possa vir a ser carregada na memória cache. Para isso, alguma outra página já existente na me- mória cache precisa ser descarregada. Podemos, assim, optar por des- carregar a página menos utilizada (LRU – least recently used) ou a que está a mais tempo carregada (FIFO – first in, first out). Decidida a página que será descarregada da memória cache, temos que providenciar meios para sua gravação em disco, pois, até o mo- mento, vários itens de dados dessa página estavam sendo atualizados somente em memória e não podemos perdê-los. Para isso, a técnica normalmente utilizada se chama atualização in loco, a qual consiste em regravar a página que se encontrava em memória na mesma posição que estava em disco, sobrescrevendo os dados que lá estavam. Nesse ponto, surge a necessidade da criação de uma estrutura de log que permita guardar uma cópia do conteúdo dos dados como eles eram antes da atualização. Essa cópia de segurança da página que será atuali- zada logo em seguida no disco deve ser gravada fisicamente no log, antes que a gravação da página dos próprios dados seja feita. Essa técnica é chamada de registro adiantado em log ou write-ahead logging. 82 Banco de Dados II Chegamos ao ponto em que uma nova estrutura de recuperação é conhecida: o registro de log. Esse, criado para cada um dos eventos de atualização de páginas de dados em disco, pode ter estruturas ligeira- mente diferentes, conforme a finalidade ou estratégia de recuperação a ser usada. São elas: Para refazer automaticamente uma atualização (REDO). Ok si Ok si /S hu tte rs to ck Caso tenhamos a necessidade de usar o arquivo de logs para refa- zer atualizações perdidas, devemos ter uma cópia de cada página de dados atualizada, com sua imagem após a atualização. Para desfazer automaticamente uma atualização (UNDO). Ok si Ok si /S hu tte rs to ck Se precisarmos utilizar o arquivo de log para desfazer atualizações realizadas, devemos possuir uma cópia de cada página atualizada, com sua imagem antes da atualização. Ok si Ok si /S hu tte rs to ck Para algum algoritmo de UNDO/REDO. Na hipótese de ocorrer alguma situação em que tanto a operação de UNDO quanto a de REDO tenham que ser executadas, precisamos de uma estrutura de log que mantenha uma cópia da página antes e, ainda, depois da atualização. Para técnicas de controle de concorrência que não previnem rollback em cascata. Ok si Ok si /S hu tte rs to ck Nesse caso, alguns outros tipos de entradas são requeridos tam- bém no arquivo de log. No vídeo Introdução ao Log de Transações do SQL Server, publicado pelo ca- nal Dbbits, você verá todo o processo de criação de um banco de dados, a alimentação de dados e a execução de transações sobre esse banco de dados, verificando qual é o impacto dessas operações sobre os arquivos de log. Poderá ver também as estruturas de log criadas e como elas se expandem após a execução das transações. Disponível em: https:// www.youtube.com/ watch?v=tA20qqsykKc. Acesso em: 10 dez. 2020. Vídeo https://www.youtube.com/watch?v=tA20qqsykKc https://www.youtube.com/watch?v=tA20qqsykKc https://www.youtube.com/watch?v=tA20qqsykKc Técnicas de recuperação em banco de dados 83 Podemos ver que os sistemas gerenciadores de bancos de dados têm um importante papel no processo de recuperação de falhas que venham a ocorrer e possam comprometer o conteúdo de um banco de dados, bem como que diversas estruturas de recuperação podem ser requeridas. Felizmente, toda essa complexidade é transferida para o SGBD e libera os programadores de seu controle e execução. Algumas estratégias adicionais são utilizadas pelo SGBD para mi- nimizar a quantidade de páginas que devem ser mantidas em cache e para permitir quedados atualizados possam ser acessados mais ra- pidamente em memória – entre eles, a gravação antecipada de alguns dados em disco ou o compartilhamento de páginas do cache. Todos esses benefícios criados, mantidos e gerenciados pelo SGBD permitem que os recursos necessários à plena recuperação dos dados de um banco de dados sejam possíveis, seja por um processo automático, no caso de falhas não catastróficas, ou por um processo manual, se forem falhas catastróficas. Outra estrutura utilizada na recuperação de um banco de dados é o checkpoint. Um checkpoint é um registro gravado no arquivo de log in- dicando que, naquele ponto (ou momento), o sistema operacional for- çou a gravação em disco de todas as páginas que estavam em buffer e que haviam sido alteradas. Ou seja, qualquer transação que tenha rea- lizado a confirmação de uma transação (commit) antes do checkpoint não precisa ser refeita caso aconteça uma falha no sistema. Figura 2 Estrutura do arquivo de log com checkpoint transação-1 transação-2 transação-N checkpoint-A1 transação N+1 transação N+2 checkpoint-2 arquivo de log Fonte: Elaborada pelo autor. Esse checkpoint é gerado para que o processo de recuperação (desfazer ou refazer algumas transações após uma falha) seja mais ágil. 84 Banco de Dados II Como o arquivo de log de transações tem uma quantidade enorme de registros a ser inspecionada pelo sistema gerenciador de banco de dados logo após a ocorrência da falha, visando identificar quais transações precisam ser desfeitas e quais precisam ser refeitas, pontos interme- diários são criados por meio de um checkpoint. Isso permite que o SGBD localize o último checkpoint realizado com sucesso e prossiga com as verificações somente a partir desse ponto. Nesse momento, o sistema de recuperação gera duas listas distin- tas por meio do log: uma lista de transações para UNDO e uma lista de transações para REDO, executando, nessa ordem (primeiro o UNDO e depois o REDO), os procedimentos que permitam restabelecer os da- dos do banco de dados a uma situação de estabilidade. Para que um checkpoint seja executado e devidamente registrado no arquivo de log, o sistema gerenciador de banco de dados deve exe- cutar uma série de ações, listadas a seguir. • Suspensão temporária de todas as transações Para que uma imagem estática das páginas existentes em buffer possa ser gravada em disco, devemos garantir que qualquer transação não modifique nem uma porção de nenhuma das páginas em memó- ria. Por isso, todas as transações em andamento serão interrompidas até que o checkpoint termine. • Gravação de todas as páginas modificadas em memória Quanto maior for o buffer alocado para cache de páginas do BD, maior será o número de páginas mantidas em memória. O SGBD deve, então, passar em cada uma das páginas e identificar se elas so- freram ou não alterações desde que foram carregadas e desde o úl- timo checkpoint. Somente após isso, as páginas que foram alteradas são gravadas em disco. Isso visa reduzir a quantidade de gravações necessárias, diminuindo o tempo de suspensão de todas as transações que ocorrem nesse momento. • Gravação de um registro de checkpoint no log Sendo finalizada a gravação em disco de todas as páginas atuali- zadas em memória, o arquivo de log recebe um registro informando que, naquele instante, o checkpoint foi concluído. Com isso, o arquivo de log é também gravado em disco para evitar que a informação do checkpoint possa ficar somente em cache e seja perdida. Técnicas de recuperação em banco de dados 85 • Retomada das transações suspensas Após assegurado que o arquivo de logs está atualizado, as transações suspensas podem ser restabelecidas aos seus pontos atuais de execu- ção, dando prosseguimento aos processos em andamento. Apesar de o checkpoint ser uma estrutura de grande valia para a garantia da estabilidade dos dados, um cuidado especial precisa ser tomado quanto à frequência de chamadas para esse processo. Caso ele seja feito frequentemente, as interrupções de todas as transações em andamento de modo muito repetitivo podem im- pactar no desempenho dos sistemas de informação. Se ele for feito com pouquíssima frequência, ainda podemos deixar de ter pon- tos de recuperação adequados. Normalmente, é possível avaliar o intervalo entre checkpoints medindo a quantidade de transações confirmadas desde o último checkpoint ou o tempo gasto entre dois checkpoints. Até esse ponto, vimos estruturas gerais que são utilizadas por diversas técnicas de recuperação de dados em um banco de dados. A seguir, veremos algumas das técnicas utilizadas, suas características e os modos de operação. 4.3 Técnicas de recuperação Vídeo A primeira técnica de recuperação a ser vista chama-se atualização postergada. Como o próprio termo já informa, todas as atualizações a serem realizadas no banco de dados serão postergadas até o momen- to em que a transação responsável por elas seja confirmada (commit). Essa técnica tem como vantagem principal o fato de que, como ne- nhum dado atualizado por uma transação será efetivamente gravado em disco, caso tenhamos alguma ocorrência de falha, poderemos sim- plesmente retomar a execução da mesma transação sem que qualquer intervenção sobre o banco de dados seja necessária. Sob o ponto de vista prático, podemos dizer que essa técnica não exige recuperação do banco de dados, uma vez que não teve qual- quer risco de ter comprometido a estabilidade do mesmo, visto que não atingiu seu ponto de confirmação (commit). Por outro lado, caso tenha sido realizado o commit, o banco de dados já estaria com sua estabilidade assegurada. 86 Banco de Dados II Enquanto uma transação que utiliza essa técnica não atinge seu ponto de confirmação, todas as atualizações que ela realiza são re- gistradas somente nas páginas em cache e no arquivo de log. Ao atingir seu ponto de confirmação (commit), os dados do log e as páginas atualizadas em memória são gravados em disco (registro adiantado em log, técnica já explicada). Se uma transação de atualização for longa e envolver muitas pági- nas de dados, precisaremos então manter em memória todas essas páginas por um longo período. Essa característica torna inviável o uso dessa técnica para alguns tipos de transações e, portanto, nem sempre pode ser adotada. Além disso, essa técnica é reconhecida também como o algoritmo de NO-UNDO/REDO, o que significa que não será necessário desfazer nenhuma atualização, pois efetivamente nada foi mudado no banco de dados até o ponto de confirmação. Porém, caso durante o processo de confirmação e a respectiva gravação dos dados existentes em memória para o disco venha a ocorrer alguma falha, a execução da transação será possível com base no arquivo de log já previamente gravado du- rante a execução da transação. Outra técnica de recuperação existente está associada a uma es- tratégia denominada de atualização imediata. Nessa estratégia, todos os comandos de atualização do banco de dados executados por meio da SQL em uma transação geram o efeito imediato de que os dados já são atualizados também nas páginas de dados do BD em disco, sem que tenhamos que aguardar a transação chegar ao seu ponto de confirmação (commit). Para que essa abordagem funcione corretamente, temos que combinar uma estratégia de atualização de logs chamada de registro postergado. Refere-se, exatamente, ao comportamento contrário do que acontecia na atualização postergada que usava um log antecipado. Considerando que os dados são atualizados em disco, nas páginas de dados do banco de dados, no exato momento em que os comandos SQL requisitam alguma atualização, temos como algoritmos de recupe- ração duas possibilidades: Técnicas de recuperação em banco de dados 87 • UNDO / NO REDO Caso a técnica de recuperação garanta que todas as atualizações sejam realizadas e gravadas em disco, antes da transação se efetivar, e encontrarmos então transações já efetivadas na lista de recuperação,essas não precisarão de nenhum procedimento de REDO, pois significa que os dados estão todos preservados. • UNDO / REDO Se a técnica de recuperação permitir que uma transação seja efeti- vada, mas que exista um atraso na gravação em disco dos seus dados, poderemos encontrar transações a serem recuperadas (visto que al- guns dados ainda não estavam gravados) mediante um processo de UNDO e REDO. Ou seja, a transação terá que ser refeita, porém antes aquelas atualizações já gravadas em disco precisarão ser desfeitas. Ao desfazer as gravações parcialmente completadas, a transação estará pronta para ser refeita em toda a sua extensão com reatualização de todos os seus dados. As técnicas vistas para recuperação de dados em um banco de dados, durante a execução de uma transação que tenha sido afeta- da por uma falha qualquer, foram consideradas todas do ponto de vista da execução de um único banco de dados. No entanto, sabe- mos que topologias mais complexas de alguns sistemas de informa- ção podem requerer o uso de bancos de dados distribuídos, sejam eles homogêneos (de um mesmo fornecedor) ou heterogêneos (de diferentes fornecedores). Nesse caso, temos que considerar, ainda, a aplicação de técni- cas de recuperação de falhas em transações distribuídas, o que pode significar a agregação de novas dificuldades advindas não so- mente da sincronização de eventos de transações concorrentes em um nó, mas também de transações que podem ser segmentadas em vários nós da rede. Uma transação distribuída é aquela na qual parte de seus coman- dos SQL são executados em um banco de dados e parte dos comandos SQL em outro BD, ou aqueles casos em que um mesmo comando SQL acaba por interagir com diferentes bancos de dados. No texto Visão geral da restauração e recuperação (SQL Server), você poderá conhecer os recursos de restauração e recupe- ração que o Microsoft SQL-Server disponibiliza, tendo assim uma visão prática de como um pro- duto comercial aborda as questões conceituais aqui apresentadas. Disponível em: https://docs. microsoft.com/pt-br/sql/relational- databases/backup-restore/ restore-and-recovery-overview- sql-server?view=sql-server-ver15. Acesso em: 10 dez. 2020. Leitura https://docs.microsoft.com/pt-br/sql/relational-databases/backup-restore/restore-and-recovery-overview-sql-server?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/backup-restore/restore-and-recovery-overview-sql-server?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/backup-restore/restore-and-recovery-overview-sql-server?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/backup-restore/restore-and-recovery-overview-sql-server?view=sql-server-ver15 https://docs.microsoft.com/pt-br/sql/relational-databases/backup-restore/restore-and-recovery-overview-sql-server?view=sql-server-ver15 88 Banco de Dados II Nessa situação, o sistema gerenciador de banco de dados dis- tribuído deverá ter capacidade de gerenciar a recuperação de transações e dados de modo distribuído. Temos, com isso, um me- canismo de recuperação que pode ocorrer em dois níveis, sendo um o nível global e outro o nível local. Figura 3 Arquitetura de transações distribuídas Transação local Transação local Transação local Transação global BD 1 BD 2 BD 3 Fonte: Elaborada pelo autor. Em um ambiente como esse, a confirmação de uma transação é feita por meio de um protocolo denominado two-phase commit, ou confirmação em duas fases. A primeira fase é intitulada preparação, enquanto a segunda fase é chamada de confirmação. Isso garantirá que os diversos nós participantes da transação distribuída possam trabalhar de modo coordenado pelo nó global. O processo de two-phase commit segue o seguinte modelo: • uma transação é iniciada e requer a participação de mais de um nó do banco de dados; • cada nó prossegue com sua parte do processamento da transação, executando os comandos ou porções de coman- dos SQL a ele submetidos; • ao finalizar as tarefas recebidas para serem executadas na- quele nó, o mecanismo de coordenação local de transações sinaliza para o mecanismo de coordenação global que sua transação local está pronta para fazer sua confirmação local (commit); Técnicas de recuperação em banco de dados 89 • o mecanismo de coordenação de transações global aguarda que todos os mecanismos locais estejam prontos para a con- firmação global – enquanto pelo menos um dos nós locais não tenha finalizado suas tarefas locais, todos os demais per- manecem aguardando; • após ter a certeza de que todos os nós locais estão prontos para a confirmação, o mecanismo de coordenação global en- via uma ordem para que os mecanismos locais executem os procedimentos de preparação da confirmação local (que sig- nifica, nesse caso, produzir logs, atualizar logs em disco, fazer checkpoints etc.); • o mecanismo de coordenação global aguarda, então, que cada nó local termine de produzir os mecanismos de recu- peração local; porém, caso o mecanismo global não receba a confirmação de um dos nós informando que finalizou suas tarefas de preparação (timeout), ou receba a informação de que houve alguma falha na execução dessas tarefas, toda a transação será invalidada; • recebendo a confirmação positiva de finalização de prepara- ção de todos os nós locais, o coordenador global envia um pe- dido para cada nó local para que eles finalizem o processo de confirmação. Nesse ponto, o coordenador global sabe que to- dos os nós locais estão prontos para finalizar suas transações e que só resta a confirmação da transação local em cada nó. Esse mecanismo de confirmação em duas fases assegura que ou todos os nós locais confirmem sua porção da transação global ou, se houver alguma falha em um nó local, todas as demais tran- sações locais sejam também desfeitas, voltando à lista de reexecu- ção, já discutida anteriormente. Isso poderá garantir que o objetivo principal de um sistema distribuído seja o de ele parecer ao usuá- rio um sistema centralizado. Concluindo, podemos destacar o importante papel deste com- ponente fundamental de um sistema gerenciador de banco de da- dos: o subsistema de recuperação. Este material apresenta detalhes sobre a arqui- tetura de um banco de dados distribuído e de como os protocolos de controle de transação são implementados nesse ambiente para permitir o controle descentralizado de transações. Disponível em: https://imasters. com.br/banco-de-dados/o-que- e-banco-de-dados-distribuido. Acesso em: 10 dez. 2020. Leitura https://imasters.com.br/banco-de-dados/o-que-e-banco-de-dados-distribuido https://imasters.com.br/banco-de-dados/o-que-e-banco-de-dados-distribuido https://imasters.com.br/banco-de-dados/o-que-e-banco-de-dados-distribuido 90 Banco de Dados II Figura 4 Arquitetura de um sistema gerenciador de banco de dados COMANDOS DDL Compilador DDL Gerenciamento dos Dados Armazenados COMANDOS PRIVILEGIADOS PESQUISA INTERATIVA Compilador de Pesquisa COMANDOS DDL Compilador DDL Controle de Concorrência/Backup/ Subsistema de Recuperação TRANSAÇÕES COMPILADAS (CUSTOMIZADAS) Compilador da linguagem hospedeira PROGRAMAS DE APLICAÇÃO Catálogo do Sistema/ Dicionário de Dados execução execução D A B E C Usuários casuais Programadores de aplicação Usuários parametrizáveisEquipe DBA BANCO DE DADOS ARMAZENADO Pré-compilador Processador de Banco de Dados em tempo de Execução (runtime) Fonte: Elmasri; Navathe, 2006, p. 26. A existência de um componente que assuma esse papel tanto no nível global e local (em sistemas distribuídos) quanto somente no nível local para sistema centralizados é, sem dúvidas, o principal fator de ga- rantia para a integridade física e lógica dos dados de um banco de dados. Gerenciar toda a complexidade de múltiplas transações con- correntes atualizando um mesmo item de dado, ou uma mesma ta- bela, poderia ser uma tarefa quase impossívelpara um programador que necessitasse desenvolver transações sobre um banco de dados compartilhado com outros sistemas de informação. Técnicas de recuperação em banco de dados 91 Isso, mais uma vez, reforça a importância da escolha de um siste- ma gerenciador de banco de dados que possa atender às demandas de recursos exigidos pelos sistemas de informação, seja pela capaci- dade de operar em modo distribuído, seja por oferecer recursos para alta disponibilidade de dados ou qualquer outra funcionalidade es- sencial à entrega de resultados aos usuários finais. As opções de sistemas gerenciadores de bancos de dados hoje disponíveis no mercado são diversas e, com certeza, podem atender a um público variado em todos esses aspectos. CONSIDERAÇÕES FINAIS As diversas técnicas de recuperação de dados implementadas e executadas, de modo automático, pelos sistemas gerenciadores de bancos de dados podem, efetivamente, significar um importante ele- mento de garantia da integridade física e lógica de um banco de dados. Imaginar que todo esse complexo mecanismo precisaria ser man- tido e gerenciado por cada um dos programadores ao criarem seus próprios programas seria impraticável. As chances de que uma falha viesse a ocorrer e não tivesse o devido tratamento seria grande, com- prometendo a integridade de todo um banco de dados. Felizmente, podemos hoje contar com mecanismos do próprio SGBD para execu- tar essa importante tarefa. ATIVIDADES 1. Justifique por que o conhecimento dos recursos de recuperação de falhas em um banco de dados é essencial para um administrador de banco de dados. 2. Por que o deadlock entre duas transações é considerado uma falha não catastrófica? 3. Qual é o recurso utilizado para otimizar a identificação de transações a serem recuperadas em um log de transações e como ele auxilia nesse processo? 4. Explique qual é a diferença entre um processo de confirmação de transações de uma fase e um de duas fases. 92 Banco de Dados II REFERÊNCIAS DATE, C. J. Introdução a sistemas de banco de dados. Rio de Janeiro: Elsevier, 2004. ELMASRI, R., NAVATHE, S. Sistemas de banco de dados. 4. ed. São Paulo: Pearson Addison Wesley, 2006. SILBERSCHATZ, A., KORTH; H. F., SUDARSHAN, S. Sistema de banco de dados. 6. ed. Rio de Janeiro: Elsevier, 2012. Data warehousing e data mining 93 5 Data warehousing e data mining Muitos dos temas relacionados ao projeto e à construção de bancos de dados estão focados, frequentemente, em uma aborda- gem orientada para os sistemas de informações, cuja finalidade é automatizar os processos operacionais dentro das organizações. Quando falamos sobre modelagem, normalização e comparti- lhamento de dados, a primeira ideia que nos vem à mente é aquela associada aos processos do dia a dia de uma organização, em que algum dado é capturado, transformado, armazenado e comparti- lhado com outros processos. Porém, no cotidiano das organizações, outra necessidade acabou por surgir, tendo que ser endereçada e tratada por meio das tecnologias da informação – essa necessidade é a produção de informações gerenciais para a tomada de decisão. Se antes a automação dos processos operacionais era o bas- tante para que uma empresa aperfeiçoasse seus resultados inter- nos e externos, agora essa realidade mudou e isso já não é mais suficiente. Atualmente, para se destacar no mercado, uma orga- nização precisa tomar as melhores decisões para que seus pro- cessos sejam executados com as estratégias sugeridas pelas áreas gerenciais. Mais importante do que fazer rápido, ou em maior quantidade, é fazer bem-feito. Por isso, surge uma nova área de conhecimento associada à construção e disponibilização de estruturas de bancos de da- dos. Essa área se dedica a transformar os dados operacionais em dados para apoio à decisão. Neste capítulo, vamos explorar os conceitos, as arquiteturas e a aplicabilidade desses novos co- nhecimentos disponíveis. 94 Banco de Dados II 5.1 Conceitos Vídeo Historicamente, os sistemas de informação requeridos pelas áreas de negócio de uma organização sempre tiveram um foco orientado para o processamento de transações. Essa orientação advinha do fato de que as atividades das áreas de negócio, com o passar do tempo, cresciam em volume e complexidade e passavam a exigir, cada vez mais, recursos humanos para sua execução. Esse crescimento fazia também com que essas atividades esti- vessem mais sujeitas a falhas em suas execuções. Quanto maior o nú- mero de pessoas envolvidas em sua execução e o volume de dados requisitados ou produzidos, maior era o índice de falha agregado aos processos de negócio. Ou seja, além do crescimento da própria equipe necessária à execução das tarefas, era gerado um aumento de custo operacional; ainda, as falhas contribuíam negativamente para um au- mento de custo final. A tecnologia da informação surge, então, como uma excelente al- ternativa para reduzir custos, melhorar a produtividade e garantir re- petitividade de processos com resultados conhecidos, isto é, melhorar o desempenho final dos processos. Essa visão acabou por gerar o que o mercado definiu como sistemas transacionais, os quais automati- zavam ou facilitavam a execução das diversas atividades operacionais das áreas de negócio. Para dar sustentação a esses sistemas, surgem os bancos de dados transacionais ou bancos de dados operacionais, pois, segundo Date (2004, p. 29), “um banco de dados é uma coleção de dados operacionais”. Des- de sua modelagem, passando pela construção e chegando até a dispo- nibilização, esses bancos de dados tinham como foco as entidades e os relacionamentos envolvidos nas transações de uma ou mais áreas da organização. Os processos gerenciais, por sua vez, continuavam sendo executa- dos predominantemente por pessoas que centralizavam a tomada de decisão de uma ou mais áreas, baseando-se nos dados operacionais que recebiam. Com o crescimento da disponibilização de dados opera- cionais, muitas áreas começaram a requerer a capacidade de sintetiza- ção ou sumarização desses dados. Data warehousing e data mining 95 Se em nosso banco de dados tínhamos todos os dados relativos às vendas de produtos de nossa empresa no último ano, teríamos agora que ter a capacidade de saber quanto cada linha de produto vendeu a cada mês, tanto em quantidade de vendas quanto em valor total vendido. Manipular os bancos de dados operacionais para obter essas infor- mações sumarizadas, ou esses totalizadores, passou a ser uma tarefa constante e, de certo modo, essencial a nível gerencial. Nesse momen- to deixa de ser importante ter a capacidade de vender com eficiência, tendo apoio de sistemas transacionais, mas passa a ser vital monitorar, por meio de indicadores, todo o desempenho da área de vendas. Sur- gem, assim, os novos sistemas, que seriam denominados sistemas de apoio à decisão. Esses sistemas de apoio à decisão requerem não mais informações detalhadas sobre cada uma das transações de negócio, e sim informa- ções sumarizadas com base nelas. Precisamos, por exemplo, de tota- lizações, médias, ordenações e agrupamentos dos dados operacionais que já temos em nossos bancos de dados convencionais. A primeira abordagem para a obtenção desses dados agrupados foi procurar uti- lizar funções que os próprios sistemas gerenciadores de bancos de da- dos passaram a implementar. Desse modo, funções como somatórios, médias, ordenações, agrupamentos etc. começaram a ser implementa- das junto à linguagem SQL a fim de que os programadores pudessem produzir dados sumarizados. Entretanto, com o passar do tempo, o crescimento do volume de dados operacionais e a necessidade, cada vez maior, de obter dados sumarizados em tempo hábil acabaram por demonstrar que as fun- ções básicas implementadas pela linguagem SQL não seriam suficien- tes para dar conta da tarefa de produzir dados para apoio à decisão de modo adequado. O fato de termos, por exemplo, que ler diariamente (ou até de hora em hora) umabase de dados com mais de um milhão de notas fiscais emitidas para extrair dados sumarizados tinha dois impactos negati- vos. Primeiro, o tempo gasto na leitura de todos esses dados; segun- do, o impacto sobre o desempenho do banco de dados operacional enquanto essa leitura era executada. Novas notas ficais poderiam ter maior tempo para serem geradas se, quando estivessem sendo produ- 96 Banco de Dados II zidas, um processo de leitura com grande volume de dados estivesse acontecendo concorrentemente. Com isso, pesquisadores passaram a estudar e avaliar novos mo- delos para a implementação de bancos de dados que permitissem a geração e manipulação de dados sumarizados e pré-armazenados, sem que isso gerasse impacto sobre os bancos de dados operacionais. Logo, nos estudos realizados, ficou evidente que estávamos tratando de dois conjuntos de dados distintos. Dessa forma, não seria adequado tentar resolver o problema da ge- ração e manipulação de dados sumarizados utilizando a mesma base de dados operacional, em que as transações de negócio eram processa- das e armazenadas. Assim, a linguagem SQL – que tinha como finali- dade agregar facilidades para que os programadores manipulassem dados operacionais em bancos de dados convencionais – ficaria dedi- cada exclusivamente a essa finalidade, e um outro tipo de linguagem e até mesmo de banco de dados seria planejado, construído e utilizado para fins de tomadas de decisões. Dessa maneira, a tomada de decisão não estaria mais dependente dos dados operacionais que continuam a ser gerados no dia a dia, mas sim baseada em um subgrupo de dados extraídos e enviados para um ambiente especialmente construído para manter dados históricos sumarizados. Hoje, muitas aplicações ainda utilizam a linguagem SQL para ob- tenção de indicadores, totalizadores, sumarizações etc. Essa aborda- gem tradicional continua sendo viável e aplicável em ambientes com menores volumes de dados operacionais. Entretanto, sempre que o volume de dados históricos for muito elevado, recomenda-se que um sistema de apoio à decisão seja construído com uma abordagem específica para essa finalidade, não só para que a própria obtenção de dados sumarizados seja otimizada, mas também para não com- prometer o ambiente operacional com interferência de processos de extração de dados. Além disso, como a produção de informações de tomada de decisão requer cada vez mais agilidade e maior especialização, um novo termo surgiu associado aos sistemas de apoio à decisão. Os sistemas tradi- cionais de processamento de transações, que eram conhecidos pela sigla OLTP (Online Transaction Processing), agora são complementados pelos sistemas OLAP (Online Analytical Processing), responsáveis pela Data warehousing e data mining 97 geração on-line de informações analíticas por meio de estruturas de bancos de dados especialmente construídas para esse fim. Figura 1 Sistemas OLTP x OLAP OLTP OLAP dados operacionais dados sumarizados indicadores Fonte: Elaborada pelo autor. Essa abordagem de utilização de dados sumarizados para apoio à decisão deu origem a vários novos termos e denominações de tecnolo- gias no mercado de banco de dados e de sistemas de informação. Um dos termos frequentemente associados a esse tipo de sistema é o BI, ou business intelligence. Esse termo pode ser utilizado tanto para denominar a finalidade de um sistema de apoio à decisão – ou seja, ele seria destinado a criar condições de agregar “inteligência de negócio” ou inteligência ao negócio –, como também dar nome à uma nova área de especiali- zação dentro daquela de tecnologia da informação, sendo a área que pesquisa, implementa, oferece e gerencia soluções de apoio à decisão para trazer “inteligência de negócio” às corporações. Assim, pessoas podem trabalhar com business intelligence ou com ferramentas de apoio à decisão, bem como podem ser especialistas em BI ou em tra- zer “inteligência de negócio” para as organizações por meio de siste- mas de apoio à decisão. Como consequência do surgimento dessa nova área de especia- lização, em que profissionais, métodos e ferramentas foram desen- volvidos para atender a uma nova demanda das organizações, outra nova terminologia e tecnologia foi também incorporada: o data mi- ning. Esse termo, traduzido em português para mineração de dados, define uma nova abordagem para utilização de dados operacionais e de dados sumarizados. No data mining, nosso objetivo maior é sermos capazes de desco- brir regras ou obter novos dados com base naqueles que já temos ar- mazenados. Essas técnicas e, consequentemente, as tecnologias a elas associadas precisam não só ser capazes, por exemplo, de manipular um grande conjunto de dados, produzindo alguma forma de sumari- No vídeo Quais perguntas o BI responde?, publicado por Rafael Piton, será possível compreender o papel dos sistemas de business intelligence nas organizações. Quais são as respostas que eles procuram responder? Que finalidade têm? Você poderá ver exemplos e entender se realmente vale a pena explorar essa nova abordagem. Disponível em: https://www. youtube.com/watch?v=LSRlpl2iolY. Acesso em: 5 jan. 2021. Vídeo https://www.youtube.com/watch?v=LSRlpl2iolY https://www.youtube.com/watch?v=LSRlpl2iolY 98 Banco de Dados II zação, como também de descobrir algum tipo de implicação entre os dados manipulados. O termo mineração de dados se assemelha justamente à atividade de mineração de rochas, na qual grandes volumes de rochas – às vezes da ordem de toneladas – são processados para se encontrar algo va- lioso, porém em pequena quantidade. Isso se refere a algo como pro- cessar uma tonelada de rochas para encontrar dez gramas de ouro ou, talvez, até não encontrar ouro nenhum, pois o lugar escolhido para mi- neração não era adequado para que o ouro fosse encontrado. Muitas procuras podem, portanto, dar muito trabalho e resultar em pouco ou até mesmo nenhum resultado prático. Na tarefa de data mining, devemos ter um objetivo de procura ou algo pelo qual procuramos. Imagine que, ao minerar rochas, você deve primeiro estabelecer um objetivo, como encontrar ouro, para depois escolher pelo menos um local propício para realizar essa atividade. Não ter um objetivo definido ou não saber onde procurar pode levar a um resultado negativo de busca. O objetivo das técnicas de data mining em um banco de dados deve também estar baseado em um objetivo estabelecido. Por exemplo, en- contrar qual é o perfil de idade dos investidores que têm maior lucro na bolsa de valores. Sabendo ser esse nosso objetivo de procura, po- demos buscar, entre todos os investimentos feitos na bolsa de valores, quais foram os que deram maior retorno em um determinado período; uma vez identificadas as idades dos investidores que fizeram aque- las operações, podemos concluir que os mais jovens são os que mais arriscam e, portanto, têm maior retorno sobre seus investimentos. Atualmente, com o advento da ampla utilização de técnicas de inteligência artificial associada às ferramentas de data mining, uma nova possibilidade foi aberta: a de que podemos descobrir regras (como a de que investidores mais jovens arriscam e lucram mais na bolsa de valores) de modo automático, ou seja, sem termos isso como objetivo de procura. Desse modo, para exemplificar, podemos submeter uma grande massa de dados para análise de uma ferramenta da data mining e aguardar que a ferramenta procure, identifique e nos aponte corre- lações entre diversos dados existentes nessas bases. Podemos, ainda, identificar que as pessoas com mais sucesso na bolsa de valores são Data warehousing e data mining 99 aquelas que diversificam mais seus investimentos. Talvez esse não seja originalmente um objetivo da nossa busca, porém ele pode ser derivado dos dados analisados. Temos, portanto, sistemas de apoio à decisão, com ou sem fun- ções de data mining, mas ambos com a finalidade de serem voltados ao business intelligence. Dessemodo, todos esses sistemas podem contribuir com o processo de gestão direcionando a tomada de de- cisão, que antes seria executada somente com a percepção de cada um dos gestores. O apoio de um sistema de tomada de decisão se mostra cada vez mais importante nos ambientes que envolvem grandes volumes de transações de negócio. Como a maior parte das empresas tem hoje focado em “escalar negócio” – ou seja, realizar muitas transações com valor de venda menor, visando ao crescimento exponencial –, cada vez mais temos o crescimento de volume de dados operacionais e, por consequência, o aumento da demanda por sistemas de apoio à decisão. Inicialmente, os sistemas gerenciadores de bancos de dados se desti- navam somente à criação de bancos de dados operacionais. No entan- to, com a evolução da demanda por sistemas de apoio à decisão, muitos dos fornecedores desses sistemas começaram a oferecer também pla- taformas para criação de outras modalidades de bancos de dados. Esses novos bancos de dados orientados aos sistemas de apoio à decisão passaram a ser chamados de data warehouses. Um data warehouse é, por definição, um grande depósito de dados para re- ter históricos de transações de negócio, permitindo que esses dados possam ser sumarizados a fim de produzir indicadores que apoiem o processo de tomada de decisão. Segundo Elmasri e Navathe (2006, p. 647), “comparados com os bancos de dados transacionais, os data warehouses são não voláteis. Isso significa que a informação no data warehouse muda muito menos frequentemente e pode ser considera- da como não sendo de tempo real e com atualização periódica”. Enquanto um banco de dados tem uma modelagem de dados orientada ao mapeamento de entidades e seus relacionamentos, ar- mazenando dados de transações com menor período de retenção, um data warehouse tem uma estrutura particular de dados orientada para grandes períodos de retenção de dados. 100 Banco de Dados II Por serem depósitos de dados que retêm grandes volumes e vas- ta variedade de dados, os data warehouses podem possuir conjuntos distintos de dados, os quais podem ser orientados a outra área de ne- gócio, como recursos humanos, financeiro, logística, produção etc. A percepção de que um data warehouse poderia ser segmentado em unidades menores com foco em áreas distintas de negócio gerou o conceito de data marts. Um data mart é definido como uma porção de um data warehouse, sendo essa focada em reter os dados de uma ou mais áreas de negócio. Eventualmente, outro termo tem sido referenciado na área de ban- co de dados, o data lake. Um data lake é um agrupamento dos mais diversos tipos de dados de uma organização, porém em formato bruto, ou seja, sem uma modelagem específica ou sem um tratamento prévio para filtragem ou classificação. Esses dados são frequentemente utiliza- dos para processos que requerem grande quantidade de amostragem, como aplicações de inteligência artificial, de processamento preditivo etc. Assim como os data warehouses, eles também estão relacionados ao conceito de big data, no entanto diferem de um data warehouse, pois este tem um modelo de dados estabelecido e um processo de fil- tragem e classificação desses dados. Justamente com a finalidade de realizar um tratamento prévio de um grande volume de dados, preparando-os para os sistemas de apoio à decisão, é que surgiram as ferramentas classificadas como ETL. Essa denominação vem das letras que representam, respectivamente as funções da ferramenta, que são: extract, transform e load – isto é, extrair, transformar e carregar. Como temos um grande universo de dados operacionais que devem ser transformados em dados analíticos para que possam ser facilmen- te manipulados por OLAP, é necessário dispor de meios para realizar esse processo de maneira sistemática e automática. As ferramentas de ETL possuem recursos para que, após um tempo predefinido ou alguns eventos predeterminados, uma rotina de extração e transformação de carga dos dados aconteça. A primeira etapa, que é a extração dos dados, pode acontecer ba- sicamente de dois modos distintos: por iniciativa do próprio ambien- te transacional que, ao perceber que chegou o momento de proceder Data warehousing e data mining 101 o envio de novos dados produzidos no ambiente transacional, faz a remessa desses dados para o processo de transformação, ou por ini- ciativa do ambiente OLAP que, também ao perceber que chegou o mo- mento de obter novos dados para realizar atualizações nos indicadores que foram previamente produzidos, requisita ao ambiente transacio- nal os novos dados necessários para realizar a transformação adequa- da sobre eles. Segundo Silberschatz, Sundarshan e Korth (2012), esses modelos de cargas são respectivamente chamados de arquitetura con- trolada pela origem e arquitetura controlada por destino. A escolha da periodicidade e do universo dos dados a serem extraí- dos em cada ciclo de atualização do data warehouse ou do data mart é uma característica de cada processo em particular. Quanto menor for a periodicidade de extração, menor será o volume da massa de dados a ser processada e, por conseguinte, menor o tempo gasto na execução dessa tarefa. Grande parte das ferramentas de ETL ofere- ce como alternativa uma estratégia de carga diferencial de dados, na qual somente aqueles dados que não estão no data warehouse são processados. Já outras ferramentas eventualmente podem requerer que toda a estrutura de dados do data warehouse seja recriada a cada nova carga. A segunda etapa do processo, que é a transformação dos dados extraídos pela fase inicial, é requerida para que os dados brutos ou naturais obtidos nos sistemas de informação transacionais sejam pre- parados para um melhor processamento no ambiente OLAP. Um exemplo de um processo de transformação frequentemente utilizado é a “desnormalização” dos dados obtidos em um banco de dados. Códigos, siglas e outras representações codificadas de alguns dos dados obtidos em um banco de dados podem ser modificados para apresentar dados textuais, como descritivos, nomes etc. Essa conversão facilitará aos sistemas OLAP o processamento e a apresen- tação dos dados em suas plataformas. A terceira etapa, que é a carga, será executada de modo síncrono com a estratégia de extração dos dados. Sendo assim, se a extração for feita de modo diferencial, a carga também utilizará um processo diferencial; já se a extração for integral, então a carga deverá utilizar um processo igualmente integral. Neste texto, você poderá conhecer detalhes sobre as características de um data warehouse, o modo como é concebido e implementado e suas principais diferenças em relação aos ambientes de bancos de dados convencionais, bem como ver conceitos sobre data marts e data lakes. Disponível em: https://www. oracle.com/br/database/ what-is-a-data-warehouse/. Acesso em: 5 jan. 2021. Leitura https://www.oracle.com/br/database/what-is-a-data-warehouse/ https://www.oracle.com/br/database/what-is-a-data-warehouse/ https://www.oracle.com/br/database/what-is-a-data-warehouse/ 102 Banco de Dados II Os dados já transformados são armazenados em estruturas de dados, sendo essas modeladas por meio de técnicas específicas, se- jam elas relacionais ou não relacionais. A arquitetura interna de cada produto pode utilizar sua própria estrutura proprietária de armazena- mento, visando sempre trazer diferenciais de performance e flexibili- dade perante seus concorrentes. Nesse aspecto, diferentemente dos padrões estabelecidos para o modelo relacional destinado a sistemas OLTP, que seguem uma padronização, as soluções OLAP podem apre- sentar arquiteturas e modelos não padronizados. O fato de não existir uma padronização nesses modelos não chega a ser um problema, pois, normalmente, eles estão vinculados às suas próprias ferramentas de ETL e não a ferramentas genéricas. Assim, uma vez definida a massa de dados que deve entrar no processo de extração em uma fontede dados relacional padrão, o restante do pro- cesso pode prosseguir orientado a um ou a outro produto específico. Com base nesses conceitos abordados até aqui, podemos prosse- guir para a análise das arquiteturas utilizadas pelas tecnologias orien- tadas a business intelligence. 5.2 Arquitetura Vídeo Dentre as estruturas de dados que poderemos encontrar associa- das à área de business intelligence, podemos ter: bancos de dados rela- cionais convencionais, estruturas híbridas relacionais, vetores e cubos multidimensionais, entre outras. Cada uma delas pode ser orientada a diferentes finalidades e produzir com maior ou menor facilidade as informações de apoio à decisão necessárias. A maneira como esses dados estão armazenados lógica e fisica- mente pode variar, mas, de modo geral, podemos estabelecer que um data warehouse (ou data mart) será composto basicamente por um conjunto de elementos que executarão suas funções de uma forma integrada. Esses componentes são: um banco de dados para armazenar e gerenciar os dados; ferramenta de ETL; ferramenta de análise e apresentação de dados (relatórios e gráficos); e ferramen- tas de mineração de dados. https://www.oracle.com/br/database/what-is-a-relational-database/ Data warehousing e data mining 103 Figura 2 Componentes de um data warehouse carregadores de dados origem de dados 1 origem de dados 2 depósito de dados ferramentas de consulta e análise origem de dados n SGBD Fonte: Silberschatz, 2012, p. 495. Os modelos de armazenamento dos dados nesses depósitos de da- dos podem seguir quatro arquiteturas distintas, a saber: Rolap (Relational OLAP): estrutura de dados para sistemas OLAP baseada no modelo relacional clássico. Esse tipo de estrutura é mais adequado aos data warehouses de grande volume. Molap (Multidimensional OLAP): estrutura de dados para sistemas OLAP baseada em vetores multidimensionais. Esse tipo de estrutu- ra é mais adequado aos data marts de menor volume, pois requer grande quantidade de manipulação de dados em memória. Holap (Hybrid OLAP): estrutura de dados para sistemas OLAP ba- seada em uma combinação de estruturas Rolap e Molap, em que uma parte dos dados é mantida em vetores multidimensionais e a outra parte em tabelas relacionais convencionais. Dolap (Desktop OLAP): estrutura de dados para sistemas OLAP ba- seada em vetores multidimensionais que são produzidos em um servidor e depois transferidos para o desktop. Ok si Ok si /S hu tte rs to ck 104 Banco de Dados II A modelagem dos dados de um sistema OLAP requer uma aborda- gem ligeiramente diferente daquela utilizada nos sistemas OLTP. En- quanto no modelo de dados para sistemas OLPT buscamos identificar as entidades e os relacionamentos, no modelo de dados para aplica- ções OLAP nosso objetivo é modelar os fatos e as dimensões envolvi- das na obtenção dos dados analíticos. Esse modelo é conhecido como modelo estrela ou star-model; nele, temos a presença de dois tipos de tabelas distintas: as tabelas de fatos e as de dimensões. Nas tabelas de fatos, nosso interesse é em armazenar as medidas associadas a cada variável que represente um fato a ser analisado. Por exemplo, se desejamos um sistema de apoio à decisão para nos ajudar a analisar o desempenho de vendas de nossos produtos nas diversas lojas de uma rede de supermercados (os fatos), podemos então produ- zir um modelo estrela, como o da Figura 3. Figura 3 Modelo estrela da tabela de fatos, denominada vendas. info_item loja cliente vendas info_data id_item nomeitem cor tamanho categoria data mês trimestre ano id_loja cidade estado país id_cliente nome rua cidade estado cod_postal país id_item id_loja id_cliente data número preço Fonte: Silberschatz, 2012, p. 496. Nesse modelo, temos ao centro a tabela de fatos chamada vendas. Esse fato foi modelado por meio dos atributos de medidas, denomina- dos número (ou quantidade) e preço. Temos também os atributos de dimensão, que são id_item (representando o código do item vendido), id_loja (representando a loja que realizou a venda), id_cliente (represen- tando o cliente que realizou a compra) e data (representando quando a venda foi realizada). Data warehousing e data mining 105 Cada dimensão é, portanto, um elemento agrupador das ven- das. Podemos agrupar todas as nossas vendas, por exemplo, por loja, produto, cliente, data etc., ou até realizar agrupamentos com- binados, como produtos por loja, clientes por data, clientes por loja, entre outros. Ao realizar o agrupamento de todas as nossas vendas dentro de cada uma das dimensões, é possível obter vários indicadores so- bre essas vendas, como: contagem, somatória, média, valor mínimo, valor máximo etc. Essa visão do modelo estrela pode ser entendida como o mode- lo conceitual dos dados que desejamos manipular no nosso sistema OLAP. A principal função do modelo é permitir que possamos visualizar as dimensões que podem ser utilizadas para manipular e agrupar os dados relativos aos fatos de interesse. Já do ponto de vista do modelo lógico, podemos também nos referen- ciar aos dados que serão agrupados para futuro manuseio, pelos siste- mas OLAP, como uma estrutura de cubos, em que cada face do cubo pode representar uma dimensão (cor, nome item, tamanho), com seus diversos elementos de agrupamento (pequeno, médio, grande etc.). Além disso, nas interseções entre cada uma das faces, podemos ter ain- da agrupamentos de novos dados, como o total de vendas de produtos escuros e grandes, escuros e pequenos, escuros e médios, entre outros. Figura 4 Estrutura de cubo multidimensional 2 2 8escura pastel co r branca tudo saia vestido camisa nome_item calça tudo tudo grande médio pequeno tam an ho 35 10 53 20 10 8 35 20 2 5 27 62 54 34 21 77 42 45 9 18 16 4 48 164 14 7 28 40 8 5 7 22 4 7 6 12 29 5 3 1 11 Fonte: Silberschatz, 2012, p. 489. 106 Banco de Dados II O cubo é, na verdade, uma simplificação da representação de uma estrutura multidimensional, visto que ele contém somente seis faces, o que poderia nos limitar a seis dimensões. Na realidade, um cubo multi- dimensional pode ter tantas faces quantas sejam necessárias, sendo então uma figura muito mais complexa do que a vista na Figura 3. Po- rém, o conceito importante a ser percebido é que o total de dimensões e combinações entre elas é totalmente livre, podendo ser feita dois a dois, três a três, ou qualquer outra combinação necessária. Podería- mos ter, por exemplo, o total de vendas de camisas, escuras e médias, o que significaria um cruzamento entre três dimensões. Sob o ponto de vista de modelo físico dessa estrutura de dados, ou do modo como os dados são gravados em disco, cada fornecedor pode utilizar uma estratégia própria, que o diferencie em relação a seus concorrentes. 5.3 Aplicabilidade Vídeo Para que possamos efetivamente utilizar as tecnologias de business intelligence a nosso favor, deveremos estabelecer um processo de mo- delagem e projeto de nosso data warehouse. Ele pode, em algumas etapas, ser dependente das ferramentas escolhidas para esse fim, mas, de modo geral, deve seguir uma metodologia que se assemelhe à construção de um sistema de informações. Dentre as etapas que en- contramos nesse processo de construção de um sistema OLAP, temos: Ok si Ok si /S hu tte rs to ck levantamento de requisitos; modelagem dos dados; criação da área de transição de dados (staging área); definição das dimensões e dos fatos de nosso modelo estrela; definição do processo de carga dos dados; criação e atualização da documentação do DW. 1 2 3 4 5 6 Este tutorial aborda, além dos conceitos envolvidos no processo de constru- ção de uma aplicação OLAP, um exemplo de uma aplicação desen- volvida com o produto Pentaho. Desse modo, você poderá perceber como cada um dos conceitos são incorpo- rados pelas ferramentas existentes no mercado. Disponível em: https:// www.devmedia.com.br/ business-intelligence-tutorial/27855Acesso em: 5 jan. 2021. Leitura https://www.devmedia.com.br/business-intelligence-tutorial/27855 https://www.devmedia.com.br/business-intelligence-tutorial/27855 https://www.devmedia.com.br/business-intelligence-tutorial/27855 Data warehousing e data mining 107 Assim como qualquer outro sistema de informações, uma apli- cação OLAP precisa ser criada com um objetivo específico de aten- dimento de necessidades de informação. O que a diferencia é que as informações a serem produzidas serão indicadores para apoio à decisão. Se a finalidade é de apoio à decisão em relação ao processo de vendas de uma empresa, será necessário identificar que tipo de in- formações está disponível (fatos) e como essas podem ser agrupadas (dimensões), qual deverá ser a periodicidade de coleta e atualização desses dados, quem terá acesso a quais dados, bem como em que momentos eles deverão estar disponíveis. Essas e muitas outras informações coletadas nessa fase de defi- nição de requisitos para o sistema orientam as demais etapas dos trabalhos e delimitam o escopo dos trabalhos a serem realizados, aju- dando também a definir o esforço que será necessário para a entrega da aplicação OLAP. O processo de modelagem de dados para sistemas OLAP irá pro- duzir um resultado diferente do processo de modelagem de dados para sistemas OLTP, mas terá também atividades similares. Devemos identificar as fontes de dados, as diferentes versões e visões existentes para os dados disponíveis (considerando que sis- temas OLAP irão trabalhar normalmente com dados históricos e que estes podem ter sua estrutura alterada com o passar do tempo), a abrangência e completeza dos dados disponíveis, os objetivos a se- rem atingidos pelo sistema OLAP etc. De posse de todas essas informações, estamos enfim prontos para preparar as estruturas para as etapas de extração e transformação desses dados. Considerando a necessidade de realizar transformações, ade- quações e homogeneizações das diversas fontes de dados identifi- cadas, de modo a permitir que o processo de carga encontre dados compatíveis em formato e conteúdo, devemos criar uma área de transição de dados, na qual os dados brutos obtidos dos sistemas OLPT (e de históricos desses) possam ser temporariamente arma- zenados para depois sofrerem adaptações que os preparem para a etapa de carga. 108 Banco de Dados II Essa área de transição possibilita o isolamento das transformações que precisam ser feitas sobre os dados obtidos das bases transacionais originais de onde eles foram obtidos. Como os dados para sistemas OLAP normalmente são adquiridos com uma defasagem de tempo em relação às transações on-line que os geraram, essa área também per- mite que possamos agendar eventuais coletas e transferências de da- dos em tempos predefinidos. Ao conseguir identificar as fontes de dados e estabelecer uma pa- dronização entre elas, estamos aptos para criar nosso modelo estrela, definindo a estrutura das tabelas de fatos e das de dimensões. Considerando que o modelo multidimensional a ser criado te- nha cinco dimensões, devemos ser capazes de, para cada fato ar- mazenado, estabelecer sempre as cinco dimensões com as quais ele se relaciona. Não devem existir dimensões opcionais, pois isso impossibilitaria as totalizações de serem realizadas após o momento de algum cruzamento entre dimensões, visto que, dessa forma, ha- veria falta de elementos nas faces do cubo. Tendo sido criado o modelo estrela, podemos criar um processo de carga inicial e de carga incremental (a ser executado futuramen- te) que possa ser automatizado e sincronizado com eventos gera- dos por fontes de dados externas. Se, por exemplo, uma loja faz o fechamento do seu caixa com as vendas executadas no dia sempre as 20h00, podemos estabelecer um processo de transferência de dados de vendas para ser executado automaticamente todo dia às 22h00, já obtendo informações atualizadas com sucesso. A definição de periodicidade, volumes e locais onde essa carga será executada poderá depender dos requisitos levantados na primeira etapa e dos recursos oferecidos pela ferramenta escolhida para imple- mentação do data warehouse. Da mesma forma que um banco de dados tradicional possui um dicionário de dados, um data warehouse possui um elemen- to para criação dos metadados sobre esse banco de dados. Nele, temos a documentação dos requisitos, estratégias, processos e dados manipulados. Utilizando um processo como esse, seremos capazes de produzir um data warehouse consistente e orientado a produzir os resultados esperados pelas áreas de negócio da organização. Data warehousing e data mining 109 CONSIDERAÇÕES FINAIS Assim como a construção de um banco de dados transacional requer o formalismo de um processo de modelagem e projeto de sua estrutura de da- dos para que possa realmente produzir os resultados esperados pelas áreas de negócio, um data warehouse também requer um processo formal que lhe assegure que irá atender às demandas por indicadores para apoio à decisão. Se, por um lado, a finalidade de um data warehouse pode parecer di- ferente, devido ao fato de ser orientado muito mais aos níveis gerenciais do que aos sistemas OLTP, por outro lado, podemos dizer que, essencial- mente, eles cumprem a mesma finalidade de um sistema OLPT, que é a de atender às demandas de informação das áreas de negócio. De certo modo, é possível entender os sistemas OLAP como um com- plemento dos sistemas OLTP, pois dependem destes para a geração dos fatos que serão usados pelo sistema OLAP. Ou seja, sem os sistemas OLAP, os dados produzidos pelos sistemas OLTP continuariam a ter difi- culdades de serem manipulados de maneira flexível e no tempo adequa- do para geração de informações para a tomada de decisão. Isso nos mostra que conhecer tanto as técnicas de construção de bancos de dados transacionais quanto as técnicas de construção de data warehouses tornou-se uma necessidade para um administrador de banco de dados, o qual precisa estar preparado para atender às demandas de informações das organizações dos tempos atuais. Esteja preparado. ATIVIDADES 1. Explique por que os sistemas OLAP não poderiam existir sem que os sistemas OLTP tivessem sido criados. 2. Qual é a principal diferença entre um data warehouse e um data mart? 3. Quantas dimensões um cubo multidimensional pode ter? 4. Por que a staging área é importante no processo de carga de dados de um data warehouse? REFERÊNCIAS DATE, C. J. Introdução a sistemas de banco de dados. São Paulo: Elsevier, 2004. ELMASRI, R., NAVATHE, S. Sistemas de banco de dados. 4. ed. São Paulo: Pearson Addison Wesley, 2006. SILBERSCHATZ, A., KORTH; H. F., SUDARSHAN, S. Sistema de banco de dados. 6. ed. Rio de Janeiro: Elsevier, 2012. 110 Banco de Dados II GABARITO 1 Armazenamento e estruturas de dados 1. Porque os dispositivos físicos que permitiam o armazenamento de dados de entrada ainda eram limitados às mídias, que só permitiam acesso sequencial, tal como os cartões e fitas perfuradas, e, logo em seguida, pelas fitas magnéticas. Todos esses dispositivos ofereciam somente acesso sequencial aos dados. Assim, os arquivos também foram organizados como arquivos sequenciais. 2. Porque ele contará com componentes eletromecânicos que ao serem acionados implicarão em perda de tempo para se deslocar até a trilha onde o dado se encontra armazenado. Depois de se posicionar sobre a trilha necessária, deverá também aguardar a rotação do disco até o setor onde o dado esteja gravado. Por menor que seja o tempo dispendido para isso, ele sempre agregará tempo adicional que não existe num acesso feito à memória RAM. 3. Um algoritmo de hash eficiente é aquele que consegue realizar a distribuição dos registros de entrada que recebe de modo homogêneo por todos os buckets de saída sem deixar muitos buckets vazios, enquanto outros estão completamente lotados. Podemos chamar isso de dispersão dos registros. 4. Porque o espaço consumido pelo índice podecompensar o tempo gasto para o acesso direto aos registros feito por outros métodos. A utilização de estruturas de índices com árvore B+ pode também reduzir o consumo de espaço em disco para o índice. Atualmente o espaço em disco tem a cada dia seu valor reduzido (para compra e para manutenção), enquanto o tempo de resposta para acesso aos dados tem cada vez mais importância, portanto, sacrificar um pequeno espaço em disco para obter eficiência no tempo de resposta das transações é uma excelente opção. 2 Processamento e otimização de consultas 1. Porque a linguagem SQL é declarativa, ou seja, ela somente informa quais dados serão manipulados, mas não de que modo eles devem ser acessados, ficando então essa tarefa a cargo do SGBD decidir. Gabarito 111 2. Para a escolha do melhor plano de execução de um comando SQL, podemos aplicar regras heurísticas e análise de dados estatísticos obtidos do dicionário de dados. Entre essas duas estratégias não podemos apresentar uma que seja melhor, pois elas podem se complementar e ser usadas em conjunto. 3. Para que possamos reduzir a quantidade de tuplas e de atributos que serão utilizados nas operações binárias que geram grande quantidade de combinações de tuplas. Desse modo, reduzimos o tamanho das relações temporárias, o consumo de espaço em disco e até o tempo de processamento das operações subsequentes. 4. Ambas geram uma quantidade de itens no resultado que é o produto do total de itens do conjunto A e do conjunto B. Além disso, as duas operações têm a característica de ser comutativas, ou seja, se multiplicar A × B ou B × A gera-se o mesmo resultado, assim como realizar o produto cartesiano de A × B produz o mesmo resultado de B × A. 3 Gerenciamento de transações 1. Porque, se um conjunto de dados compartilhado entre diversos processos sofrer qualquer atualização enquanto esteja sendo acessado por múltiplas transações, podemos acabar por entregar dados não consistentes para todos os processos que os acessam. Assim, podem ocorrer leituras sujas, leituras não repetitivas e outros problemas similares. 2. Se após realizar todas as suas operações internas, ao seu final, uma transação não conseguir gravar os dados atualizados em disco, ou se não conseguir gerar os registros nos logs de atualização para permitir que a atualização seja reconstruída, poderemos perder a característica de durabilidade da transação. 3. Um programador pode codificar um comando de ROLLBACK quando perceber que uma condição qualquer foi encontrada pelo programa, não permitindo que as alterações realizadas até o momento sejam confirmadas. Já o sistema gerenciador de banco de dados pode executar automaticamente o processo de ROLLBACK quando perceber que alguma falha aconteceu em uma transação e que ela terá que ser reiniciada. 4. Um deadlock acontece quando uma transação A solicita acesso a um recurso X que está sendo utilizado por uma transação B, mas, nesse momento, a transação B também já se encontra esperando por um 112 Banco de Dados II recurso Y que está sendo usado pela transação A. Assim, a transação A ficará indefinidamente esperando pela liberação do recurso X enquanto a transação B ficará indefinidamente aguardando pelo recurso Y. Para finalizar esse impasse, o sistema gerenciador de banco de dados irá cancelar a transação A, a qual gerou o pedido final que originou o deadlock, permitindo que a transação B prossiga até seu final e, então, reiniciando a transação A. 4 Técnicas de recuperação em banco de dados 1. Porque os recursos oferecidos pelos bancos de dados atualmente se configuram como recursos estratégicos para que as áreas de negócio possam entregar seus resultados aos clientes. Caso um banco de dados se torne indisponível, a própria operação de uma empresa pode ser afetada. 2. Porque, após acontecer um deadlock, o sistema gerenciador de banco de dados poderá cancelar a transação causadora dessa falha, liberando a outra transação para que ela prossiga, sem qualquer perda de dados. Após isso, poderá reprocessar a transação cancelada, também sem perda de dados. 3. O checkpoint é utilizado para marcar pontos de referência dentro de um arquivo de log, permitindo que somente as transações realizadas após o último checkpoint sejam analisadas e recuperadas, o que reduz o tempo gasto nesse processo. 4. Uma confirmação realizada em duas fases possui uma fase de preparação da confirmação, que deve ser executada com sucesso por vários nós de uma rede, para depois permitir que a confirmação local da transação aconteça. No processo de confirmação de uma fase não há dependência de outros nós da rede. 5 Data warehousing e data mining 1. Porque os dados operacionais que serão produzidos pelos sistemas OLTP serão a fonte de dados para o processo de ETL que alimentará os dados em um sistema OLAP. 2. Um data mart é uma segmentação dos dados de um data warehouse, feita por meio da seleção de dados de um determinado departamento, uma área de negócio ou um assunto. Gabarito 113 3. Quantas forem necessárias. Diferentemente da ideia prévia de que um cubo teria sempre seis dimensões, e ele na verdade pode ter tantas dimensões quantas sejam necessárias, podendo ser com mais ou menos do que seis. 4. Porque diferentes fontes de dados operacionais pode ter diferentes formatos ou versões dos dados e, assim, precisamos unificar a visão desses dados, permitindo a carga de modo padronizado. Para alterar as formatações dos dados, não podemos mudar a fonte dos dados. Logo, utilizar uma área intermediária pode permitir que alterações sejam feitas sem impactar os dados operacionais originais. Código Logístico 59714 BANCO DE DADOS II Paulo Sérgio Cougo Fundação Biblioteca Nacional ISBN 978-85-387-6717-6 9 7 8 8 5 3 8 7 6 7 1 7 6 Página em branco Página em branco