15.07.2013 Views

ISCTE – ESCOLA DE GESTÃO - Universidade Técnica de Lisboa

ISCTE – ESCOLA DE GESTÃO - Universidade Técnica de Lisboa

ISCTE – ESCOLA DE GESTÃO - Universidade Técnica de Lisboa

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Algoritmos para a Geração <strong>de</strong> Hipercubos<br />

Análise do algoritmo Multi-Way<br />

RUI MANUEL CARVALHO DOS SANTOS CHAPOUTO<br />

Dissertação para obtenção do Grau <strong>de</strong> Mestre em<br />

ENGENHARIA INFORMÁTICA E <strong>DE</strong> COMPUTADORES<br />

Júri<br />

Presi<strong>de</strong>nte: Prof. Pedro Manuel Moreira Vaz Antunes <strong>de</strong> Sousa<br />

Orientador: Profª Cláudia Martins Antunes<br />

Vogais: Prof. Arlindo Manuel Lime<strong>de</strong> <strong>de</strong> Oliveira<br />

Profª. Helena Isabel <strong>de</strong> Jesus Galhardas<br />

Setembro 2007


Agra<strong>de</strong>cimentos<br />

Gostaria <strong>de</strong> agra<strong>de</strong>cer a todas as pessoas que, <strong>de</strong> alguma forma, directa ou indirectamente, contribuiram<br />

com comentários ou sugestões no <strong>de</strong>senvolvimento <strong>de</strong>sta tese.<br />

À minha orientadora, prof. Cláudia Antunes, a disponibilida<strong>de</strong> apresentada ao longo dos anos <strong>de</strong><br />

trabalho, em especial nas inúmeras revisões efectuadas a esta tese.<br />

Ao prof. Jiawei Han, pelas respostas prontas e precisas sempre que lhe foi solicitado ajuda no âmbito<br />

<strong>de</strong>ste projecto.<br />

Aos meus colegas <strong>de</strong> trabalho, pelo incentivo e paciência nas inúmeras vezes em que abor<strong>de</strong>i o assunto<br />

<strong>de</strong>ste trabalho ao longo <strong>de</strong>stes anos.<br />

Aos meus pais e irmã, pela confiança, incentivo e apoio incondicional, e não só, <strong>de</strong> todos estes anos.<br />

E à Rita, pela ajuda, empenho, orientação, visão crítica, companheirismo, paciência e apoio<br />

incondiconal, o meu agra<strong>de</strong>cimento muito especial.<br />

1


Resumo<br />

A tecnologia OLAP permite a um utilizador extrair e visualizar informação a partir <strong>de</strong> um conjunto <strong>de</strong><br />

dados <strong>de</strong> forma relativamente fácil e intuitiva, sob diferentes pontos <strong>de</strong> vista. Tipicamente, esta<br />

tecnologia é aplicada a nível dos sistemas <strong>de</strong> apoio à <strong>de</strong>cisão para produção <strong>de</strong> relatórios <strong>de</strong> negócios,<br />

marketing, orçamentos, previsões, relatórios financeiros e áreas similares. Para possibilitar a<br />

apresentação <strong>de</strong> diferentes vistas sobre os dados, as operações OLAP apoiam-se num mo<strong>de</strong>lo<br />

multidimensional com base no qual é construída uma ―imagem‖ dos dados, <strong>de</strong>signada como cubo. A<br />

construção <strong>de</strong>ste cubo implica o cálculo <strong>de</strong> agregados <strong>de</strong> dados multidimensionais, o que é uma tarefa<br />

com elevados requisitos a nível <strong>de</strong> tempo e espaço e para a qual foram <strong>de</strong>senvolvidos diferentes<br />

algoritmos. Um <strong>de</strong>sses algoritmos é o algoritmo Multi-Way, que se <strong>de</strong>staca dos restantes no sentido <strong>de</strong><br />

ter sido originalmente concebido para sistemas MOLAP, para os quais existem poucos algoritmos, e <strong>de</strong><br />

ter alcançado níveis <strong>de</strong> <strong>de</strong>sempenho bastante bons. O objectivo <strong>de</strong>ste trabalho passa por estudar esse<br />

algoritmo e propor para ele optimizações que lhe permitam resolver problemas que neste momento não<br />

consegue resolver, tais como a <strong>de</strong>ficiente gestão <strong>de</strong> memória.<br />

Palavras-chave: business intelligence, OLAP, mo<strong>de</strong>lo multidimensional, agregação<br />

2


Abstract<br />

OLAP technology allows a user to extract and visualize information from a data set in an easy and<br />

intuitive way, from different perspectives. Usually, this technology is used in <strong>de</strong>cision support system for<br />

report production on budgeting, previews, finantial issues and similar goals. The ability to see data from<br />

different perspectives is due to the fact that OLAP operations use a multidimensional mo<strong>de</strong>l to build an<br />

―image‖ of data, known as cube. The generation of cubes requires numerous multidimensional<br />

aggregates to be computed, which is a task with high needs of time and space. These high requisites<br />

motivated the <strong>de</strong>velopment of various algorithms, like Multi-Way algorithm. This algorithm was one of the<br />

few <strong>de</strong>veloped for MOLAP systems and shows good performances when compared with algorithms that<br />

follow other approaches. The goal of this thesis is to study that algorithm and <strong>de</strong>velop optimizations that<br />

would allow it to solve situations it is not able to hand as it was conceived, due to lack of memory.<br />

Key words: business intelligence, OLAP, multidimensional mo<strong>de</strong>l, aggregation<br />

3


Índice<br />

Lista <strong>de</strong> figuras .............................................................................................................................................. 6<br />

Lista <strong>de</strong> tabelas ............................................................................................................................................. 8<br />

Lista <strong>de</strong> abreviaturas ..................................................................................................................................... 9<br />

1 Introdução ........................................................................................................................................... 10<br />

1.1 Motivação .................................................................................................................................... 11<br />

1.2 Objectivo da tese ........................................................................................................................ 11<br />

1.3 Estrutura da tese ......................................................................................................................... 11<br />

2 Trabalhos prévios sobre geração <strong>de</strong> hipercubos ................................................................................ 13<br />

2.1 Mo<strong>de</strong>lo <strong>de</strong> dados multidimensional ............................................................................................. 13<br />

2.2 O operador DATA CUBE ............................................................................................................ 18<br />

2.3 Selecção <strong>de</strong> agregados para pré-computação ........................................................................... 21<br />

2.4 Computação <strong>de</strong> agregados multidimensionais ........................................................................... 22<br />

2.4.1 Algoritmos baseados em or<strong>de</strong>nação e dispersão (sorting e hashing) ................................ 23<br />

2.4.2 Algoritmos baseados em partição ....................................................................................... 27<br />

2.4.3 Algoritmos baseados em arrays .......................................................................................... 29<br />

2.5 Variantes ao problema tradicional............................................................................................... 42<br />

2.5.1 Computação da base para o topo (bottom-up computation) .............................................. 42<br />

2.5.2 H-cubing .............................................................................................................................. 43<br />

2.5.3 Star-Cubing ......................................................................................................................... 44<br />

3 Trabalho realizado .............................................................................................................................. 46<br />

3.1 Motivação .................................................................................................................................... 46<br />

3.2 Arquitectura ................................................................................................................................. 47<br />

3.3 Optimização <strong>de</strong> ―sub-treeing‖ ...................................................................................................... 48<br />

3.4 Optimização <strong>de</strong> ―sub-chunking‖ .................................................................................................. 50<br />

4 Estudo do algoritmo Multi-Way ........................................................................................................... 52<br />

4.1 Dados <strong>de</strong> teste ............................................................................................................................ 52<br />

4.2 Estudo do efeito da variação na <strong>de</strong>nsida<strong>de</strong> dos dados .............................................................. 53<br />

4.3 Estudo do efeito da variação do volume <strong>de</strong> dados ..................................................................... 55<br />

4


4.3.1 Efeito da variação do número <strong>de</strong> dimensões ...................................................................... 55<br />

4.3.2 Efeito da variação da cardinalida<strong>de</strong> das dimensões........................................................... 58<br />

5 Balanço final ........................................................................................................................................ 63<br />

6 Referências ......................................................................................................................................... 64<br />

5


Lista <strong>de</strong> figuras<br />

Figura 1 <strong>–</strong> Representação sob a forma <strong>de</strong> cubo 3D da tabela 2 [Han2001a] ............................................ 15<br />

Figura 2 <strong>–</strong> Malha <strong>de</strong> cubói<strong>de</strong>s para um cubo 4D [Han2001a] .................................................................... 16<br />

Figura 3 <strong>–</strong> Exemplo <strong>de</strong> um mo<strong>de</strong>lo multidimensional [Chanduri1997] ....................................................... 17<br />

Figura 4 - Operador CUBE para cubos 0D, 1D, 2D e 3D [Gray1997] ........................................................ 20<br />

Figura 5 - Malha <strong>de</strong> combinações possíveis para 3 atributos [Harinarayan1996] ...................................... 22<br />

Figura 6 <strong>–</strong> Pseudocódigo relativo ao algoritmo 2 N ...................................................................................... 23<br />

Figura 7 - Exemplo <strong>de</strong> uma malha <strong>de</strong> procura [Agrawal1996] ................................................................... 24<br />

Figura 8 - Parte da malha <strong>de</strong> procura transformada [Agrawal1996]........................................................... 25<br />

Figura 9 - Resultado obtido pelo algoritmo PipeSort para k = 1 [Agrawal1996] ......................................... 25<br />

Figura 10 - Árvore <strong>de</strong> cobertura mínima para a malha <strong>de</strong> procura apresentada na figura 7 [Agrawal1996]<br />

.................................................................................................................................................................... 26<br />

Figura 11 - Sub-árvores obtidas por partição da árvore da figura 10 segundo o atributo A [Agrawal1996]<br />

.................................................................................................................................................................... 27<br />

Figura 12 - Ilustração da lógica do funcionamento do algoritmo Partitioned-Cube [Ross1997] ................ 28<br />

Figura 13 <strong>–</strong> Pseudocódigo genérico do algoritmo Multi-Way ..................................................................... 29<br />

Figura 14 - Array 3D para as dimensões A, B e C, dividido em 64 chunks ................................................ 32<br />

Figura 15 - MMST para O = (A, B, C) [Zhao1997] ...................................................................................... 33<br />

Figura 16 - Requisitos <strong>de</strong> memória para duas or<strong>de</strong>nações diferentes das dimensões [Zhao1997] .......... 34<br />

Figura 17 <strong>–</strong> Representação <strong>de</strong> um cubo 3D segundo [Tam1998] .............................................................. 36<br />

Figura 18 <strong>–</strong> Representação do cubo C com 18 chunks [Tam1998] ........................................................... 37<br />

Figura 19 <strong>–</strong> MMST para o cubo C [Tam1998] ............................................................................................ 38<br />

Figura 20 <strong>–</strong> MNST para o cubo C [Tam1998] ............................................................................................. 39<br />

Figura 21 <strong>–</strong> Relação entre cubói<strong>de</strong>s e subcubói<strong>de</strong>s em relação à célula V(0, 0, 0) usando R-cubing<br />

[Tam1998] ................................................................................................................................................... 40<br />

Figura 22 <strong>–</strong> Processo <strong>de</strong> adição do chunk 0 aos chunks subcubói<strong>de</strong>s relacionados [Tam1998] .............. 41<br />

Figura 23 - Exemplo <strong>de</strong> uma H-tree [Agrawal1994] ................................................................................... 43<br />

Figura 24 - Árvore <strong>de</strong> computação top-down [Xin2003] ............................................................................. 44<br />

Figura 25 <strong>–</strong> Pseudocódigo correspon<strong>de</strong>nte à criação da MMST................................................................ 49<br />

Figura 26 <strong>–</strong> Exemplo <strong>de</strong> uma MMST para O = (A, B, C, D)........................................................................ 50<br />

Figura 27 - Pseudocódigo que ilustra o mecanismo <strong>de</strong> sub-chunking ...................................................... 51<br />

Figura 28 <strong>–</strong> Efeito da variação da <strong>de</strong>nsida<strong>de</strong> dos dados no número <strong>de</strong> leituras e escritas efectuadas por<br />

MW .............................................................................................................................................................. 54<br />

Figura 29 <strong>–</strong> Efeito da variação da <strong>de</strong>nsida<strong>de</strong> dos dados no tempo usado por MW para calcular o cubo 54<br />

Figura 30 <strong>–</strong> Efeito da variação do número <strong>de</strong> dimensões nas leituras e escritas realizadas para o<br />

algoritmo MW .............................................................................................................................................. 55<br />

Figura 31 <strong>–</strong> Efeito da variação do número <strong>de</strong> dimensões nas leituras e escritas realizadas ..................... 56<br />

6


Figura 32 - Efeito da variação do número <strong>de</strong> dimensões no número <strong>de</strong> nós da MMST explorados para o<br />

algoritmo MW .............................................................................................................................................. 57<br />

Figura 33 <strong>–</strong> Efeito da variação do número <strong>de</strong> dimensões no número <strong>de</strong> nós da MMST explorados ......... 57<br />

Figura 34 <strong>–</strong> Efeito da variação do número <strong>de</strong> dimensões no tempo <strong>de</strong> cálculo do cubo ........................... 58<br />

Figura 35 <strong>–</strong> Efeito da variação da cardinalida<strong>de</strong> das dimensões no número <strong>de</strong> leituras efectuadas ........ 59<br />

Figura 36 - Efeito da variação da cardinalida<strong>de</strong> das dimensões no número <strong>de</strong> escritas efectuadas ........ 59<br />

Figura 37 <strong>–</strong> Tempo consumido no cálculo do agregado pelas diferentes implementações para 2560000<br />

tuplos ........................................................................................................................................................... 60<br />

Figura 38 <strong>–</strong> Efeito da variação da cardinalida<strong>de</strong> das dimensões no tempo <strong>de</strong> cálculo do cubo ................ 61<br />

Figura 39- Comparação entre as leituras realizadas para diferentes cardinalida<strong>de</strong>s <strong>de</strong> dimensões ......... 61<br />

Figura 40 <strong>–</strong> Comparação entre as escritas realizadas para diferentes cardinalida<strong>de</strong>s <strong>de</strong> dimensões ...... 62<br />

7


Lista <strong>de</strong> tabelas<br />

Tabela 1 <strong>–</strong> Volume <strong>de</strong> vendas em função do tempo e do tipo <strong>de</strong> item para a cida<strong>de</strong> <strong>de</strong> Vancouver<br />

[Han2001a] .................................................................................................................................................. 14<br />

Tabela 2 <strong>–</strong> Volume <strong>de</strong> vendas em função do tempo, tipo <strong>de</strong> item e localização [Han2001a] .................... 14<br />

Tabela 3 <strong>–</strong> Roll-up das vendas por mo<strong>de</strong>lo, ano e cor adaptado <strong>de</strong> [Gray1997] ....................................... 18<br />

Tabela 4 - Roll-up das vendas por mo<strong>de</strong>lo, ano e cor como sugerido por Chris Date, adaptado <strong>de</strong><br />

[Gray1997]................................................................................................................................................... 19<br />

Tabela 5 - Resultado após computada a agregação, adaptado <strong>de</strong> [Gray1997] ......................................... 19<br />

Tabela 6 - Linhas a acrescentar à tabela 3 adaptado <strong>de</strong> [Gray1997] ........................................................ 19<br />

Tabela 7 - Cross table para as vendas da marca Chevy adaptado <strong>de</strong> [Gray1997].................................... 20<br />

Tabela 8 <strong>–</strong> Or<strong>de</strong>m das células do cubo no array [Tam1998] ...................................................................... 36<br />

Tabela 9 <strong>–</strong> Exemplo <strong>de</strong> notação utilizada para i<strong>de</strong>ntificar os agregados e seus elementos ...................... 48<br />

Tabela 10 <strong>–</strong> Plano <strong>de</strong> testes ....................................................................................................................... 53<br />

8


Lista <strong>de</strong> abreviaturas<br />

BUC Bottom-Up Computation<br />

mDC Mínimo divisor comum<br />

MDC Máximo divisor comum<br />

MMST Minimum Memory Spanning Tree<br />

MNST Minimum Number Spanning Tree<br />

MOLAP Multidimensional On-Line Analytical Processing<br />

MW Multi-Way Array<br />

OLAP On-Line Analytical Processing<br />

ROLAP Relational On-Line Analytical Processing<br />

SC Sub-Chunking<br />

ST Sub-Treeing<br />

SQL Structured Querying Language<br />

9


1 Introdução<br />

Ao longo das últimas décadas, as nossas capacida<strong>de</strong>s <strong>de</strong> gerar, recolher e coleccionar dados têm<br />

aumentado <strong>de</strong> forma significativa. A investigação crescente na área das tecnologias <strong>de</strong> informação e<br />

sistemas <strong>de</strong> bases <strong>de</strong> dados <strong>de</strong>s<strong>de</strong> a década <strong>de</strong> 70, associada ao custo cada vez menor e consequente<br />

vulgarização dos recursos <strong>de</strong> hardware, tornou prática relativamente comum o armazenamento <strong>de</strong><br />

diferentes tipos <strong>de</strong> dados em estruturas relacionais. Consequentemente, a maioria das organizações<br />

começou a manter dados sobre os seus eventos, activida<strong>de</strong>s e clientes, tais como inventários, históricos<br />

<strong>de</strong> vendas, fichas <strong>de</strong> clientes, dados sobre o mercado, entre outros. O facto <strong>de</strong> efectuar esta<br />

armazenagem po<strong>de</strong> ser convertido numa vantagem competitiva, <strong>de</strong>s<strong>de</strong> que os dados sejam analisados<br />

criteriosamente e com rigor, por forma a extrair <strong>de</strong>les informação útil. Porém, a quantida<strong>de</strong> <strong>de</strong> dados<br />

acumulados atingiu gran<strong>de</strong>s dimensões e cresceu muito rapidamente, pelo que exce<strong>de</strong>u a capacida<strong>de</strong><br />

humana para os compreen<strong>de</strong>r e analisar. Por esta razão, as <strong>de</strong>cisões não eram realmente tomadas com<br />

base na informação oculta nas bases <strong>de</strong> dados, dando origem a uma situação <strong>de</strong>signada como ―data rich<br />

but information poor‖ [Han2001a].<br />

Assim sendo, as exigências do mundo mo<strong>de</strong>rno e em constante mudança levaram à criação <strong>de</strong> várias<br />

técnicas e ferramentas para auxiliar os indivíduos encarregues das tomadas <strong>de</strong> <strong>de</strong>cisão nessa tarefa. A<br />

partir da década <strong>de</strong> 80, a área das tecnologias <strong>de</strong> informação verificou novamente um gran<strong>de</strong><br />

crescimento, com a adopção generalizada do mo<strong>de</strong>lo relacional e a intensificação da investigação na<br />

área das bases <strong>de</strong> dados, nomeadamente a nível dos mo<strong>de</strong>los <strong>de</strong> dados e <strong>de</strong> bases <strong>de</strong> dados<br />

orientados a aplicações e/ou fins específicos. Devido ao surgimento e expansão da Internet, a<br />

investigação nesta área passou a focar igualmente temas relacionados com a distribuição, partilha <strong>de</strong><br />

dados e a heterogeneida<strong>de</strong> das bases <strong>de</strong> dados. Surgiram, assim, sistemas sofisticados <strong>de</strong> apoio à<br />

<strong>de</strong>cisão que permitiram às organizações agilizar e tornar mais eficiente o processo <strong>de</strong> tomada <strong>de</strong><br />

<strong>de</strong>cisões com base nos dados armazenados. O termo datawarehousing refere-se exactamente a um<br />

conjunto <strong>de</strong> tecnologias <strong>de</strong> suporte à <strong>de</strong>cisão que possibilitam a análise da informação oculta pela<br />

quantida<strong>de</strong> <strong>de</strong> dados. Como as bases <strong>de</strong> dados operacionais estão organizadas no sentido <strong>de</strong> optimizar<br />

o uso diário e normalmente é necessária a consolidação <strong>de</strong> dados <strong>de</strong> diferentes fontes para fins <strong>de</strong><br />

suporte à <strong>de</strong>cisão, as datawarehouses são preferidas em relação às bases <strong>de</strong> dados correntes pelo facto<br />

<strong>de</strong> conterem registos históricos que agregam dados <strong>de</strong> diferentes fontes. Este tipo <strong>de</strong> repositório po<strong>de</strong><br />

ser implementado sobre os sistemas <strong>de</strong> gestão <strong>de</strong> base <strong>de</strong> dados relacionais, recorrendo a extensões <strong>de</strong><br />

SQL e métodos próprios para implementar as operações necessárias <strong>de</strong> forma eficiente. Porém, existe<br />

um outro tipo <strong>de</strong> data warehouses que implementam o mo<strong>de</strong>lo <strong>de</strong> dados multidimensional, no qual os<br />

dados são representados na forma <strong>de</strong> um cubo, implementados em estruturas especiais (por exemplo,<br />

arrays).<br />

In<strong>de</strong>pen<strong>de</strong>ntemente do tipo <strong>de</strong> implementação, um aspecto fulcral na análise <strong>de</strong> dados organizados<br />

segundo o mo<strong>de</strong>lo multidimensional é a computação eficiente <strong>de</strong> agregações segundo várias dimensões<br />

do cubo, ou seja, a computação dos vários cubói<strong>de</strong>s que compõem um cubo. Os algoritmos concebidos<br />

10


para este fim <strong>de</strong>vem levar em conta a quantida<strong>de</strong> <strong>de</strong> memória que po<strong>de</strong> ser consumida na computação<br />

dos agregados e o tempo dispendido. Apesar do interesse generalizado em torno dos sistemas <strong>de</strong> apoio<br />

à <strong>de</strong>cisão e tecnologias relacionadas, a discussão aberta sobre estes algoritmos não é uma área<br />

privilegiada <strong>de</strong> investigação académica. A maioria das implementações <strong>de</strong>stes algoritmos faz parte <strong>de</strong><br />

soluções <strong>de</strong> business intelligence <strong>de</strong>senvolvidas para comercialização e, como tal, não estão acessíveis.<br />

1.1 Motivação<br />

O uso crescente <strong>de</strong> ferramentas <strong>de</strong> apoio à <strong>de</strong>cisão faz com que as questões relacionadas com as data<br />

warehouses e o mo<strong>de</strong>lo multidimensional sejam importantes, na medida em que <strong>de</strong>terminam o<br />

<strong>de</strong>sempenho <strong>de</strong>ssas ferramentas e a qualida<strong>de</strong> dos resultados obtidos. O objectivo dos cubos é<br />

permitirem ao utilizador uma forma rápida e flexível <strong>de</strong> olhar para os dados. Neste caso, a exploração<br />

dos dados é conduzida pelo utilizador no sentido em que este não sabe à partida aquilo que quer<br />

encontrar. Existem diferentes técnicas para realizar a computação <strong>de</strong> agregados multidimensionais,<br />

sendo cada uma <strong>de</strong>las mais a<strong>de</strong>quada a <strong>de</strong>terminados problemas, e não existe uma técnica universal.<br />

Além da complexida<strong>de</strong> inerente à computação dos agregados, um dos principais problemas que se<br />

põem a estes algoritmos é o carácter dos dados, que muitas vezes são esparsos e po<strong>de</strong>m reduzir a<br />

eficiência <strong>de</strong> um algoritmo se isso não for levado em conta. Logo, os principais <strong>de</strong>safios nesta área<br />

consistem na implementação dos algoritmos <strong>de</strong> forma a que sejam eficientes e permitam obter<br />

resultados no menor espaço <strong>de</strong> tempo possível. Com efeito, a implementação po<strong>de</strong> fazer toda a<br />

diferença no <strong>de</strong>sempenho <strong>de</strong>ste tipo <strong>de</strong> algoritmos.<br />

1.2 Objectivo da tese<br />

Devido ao facto <strong>de</strong> o algoritmo Multi-Way, se apresentar como um dos mais promissores, optou-se por<br />

aprofundar o seu estudo. Assim, o objectivo <strong>de</strong>ste trabalho consiste em estudar aprofundadamente o<br />

algoritmo Multi-Way, assim como uma sua variante disponibilizada no sistema DBMiner, por forma a<br />

i<strong>de</strong>ntificar as suas limitações face a bases <strong>de</strong> dados com características variadas. Na sequência <strong>de</strong>sse<br />

estudo, foram propostas duas optimizações que lhe permitem ser aplicado com maior sucesso num<br />

maior número <strong>de</strong> situações. Esta tese formaliza a proposta <strong>de</strong>ssas optimizações e relata os resultados<br />

obtidos pelo algoritmo na presença e ausência daquelas optimizações.<br />

1.3 Estrutura da tese<br />

A tese encontra-se organizada da seguinte forma: a secção 2 <strong>de</strong>screve a investigação realizada no<br />

domínio dos algoritmos para geração <strong>de</strong> hipercubos, com especial incidência no algoritmo Multi-Way; a<br />

secção 3 apresenta o trabalho realizado, <strong>de</strong>finindo o problema que se preten<strong>de</strong> estudar no contexto dos<br />

trabalhos prévios na área e <strong>de</strong>screvendo a implementação e as optimizações propostas ao algoritmo<br />

11


Multi-Way; a secção 4 apresenta os resultados dos testes realizados para aferir o <strong>de</strong>sempenho do<br />

algoritmo numa varieda<strong>de</strong> <strong>de</strong> dados e em simultâneo avaliar o real impacto das optimizações propostas;<br />

por fim, a secção 5 faz um balanço do trabalho realizado.<br />

12


2 Trabalhos prévios sobre geração <strong>de</strong> hipercubos<br />

Esta secção apresenta os trabalhos já realizados na área <strong>de</strong> geração <strong>de</strong> hipercubos e OLAP, com<br />

especial relevância para os problemas que se põem ao cálculo <strong>de</strong> agregados multidimensionais e aos<br />

vários algoritmos que foram concebidos para ultrapassar estes problemas.<br />

2.1 Mo<strong>de</strong>lo <strong>de</strong> dados multidimensional<br />

Com a crescente quantida<strong>de</strong> <strong>de</strong> dados disponíveis, o recurso a data warehouses torna-se cada vez mais<br />

necessário e frequente. Apesar disso, o conceito <strong>de</strong> data warehouse não tem uma <strong>de</strong>finição única.<br />

Normalmente, o termo é utilizado para referir uma base <strong>de</strong> dados que é mantida separada da base <strong>de</strong><br />

dados operacional <strong>de</strong> uma organização e que está integrada com vários sistemas que permitem efectuar<br />

o processamento e análise dos dados. Uma das <strong>de</strong>finições mais usadas <strong>de</strong>fen<strong>de</strong> que a data warehouse<br />

é um conjunto <strong>de</strong> dados organizados em torno <strong>de</strong> um <strong>de</strong>terminado tópico, resultante da integração <strong>de</strong><br />

diferentes fontes <strong>de</strong> dados, mantidos <strong>de</strong> forma persistente e que expressa uma perspectiva histórica<br />

<strong>de</strong>sses dados. Segundo Inmon, o conceito <strong>de</strong> data warehouse po<strong>de</strong> ser <strong>de</strong>finido como um conjunto<br />

integrado e não-volátil <strong>de</strong> informação orientada a um <strong>de</strong>terminado tema e que expressa a variação<br />

<strong>de</strong>sses dados ao longo do tempo, po<strong>de</strong>ndo esses dados ser usados para fins <strong>de</strong> apoio a <strong>de</strong>cisões<br />

[Inmon1996].<br />

Esta separação entre a base <strong>de</strong> dados operacional e a data warehouse promove a eficiência e<br />

<strong>de</strong>sempenho <strong>de</strong> cada um dos sistemas, tendo em conta os diferentes fins a que se <strong>de</strong>stina. A principal<br />

função das bases <strong>de</strong> dados operacionais é a realização <strong>de</strong> transacções online e processamento <strong>de</strong><br />

interrogações (queries), sendo esse conjunto <strong>de</strong> operações conhecido como processamento <strong>de</strong><br />

transacções online (online transaction processing - OLTP). Em oposição, as data warehouses têm por<br />

objectivo servir <strong>de</strong> suporte à análise <strong>de</strong> dados e tomada <strong>de</strong> <strong>de</strong>cisões, pelo que sobre elas são realizados<br />

outros tipos <strong>de</strong> operações. Normalmente, tratam-se <strong>de</strong> operações que manipulam gran<strong>de</strong>s quantida<strong>de</strong>s<br />

<strong>de</strong> dados históricos, permitem a realização <strong>de</strong> sumarizações e agregações e a gestão <strong>de</strong> informação em<br />

diferentes níveis <strong>de</strong> granularida<strong>de</strong>. A este tipo <strong>de</strong> operações dá-se o nome <strong>de</strong> processamento analítco<br />

online (online analytical processing - OLAP).<br />

De uma forma genérica, uma data warehouse é composta por uma tabela <strong>de</strong> factos, on<strong>de</strong> se encontram<br />

os dados que po<strong>de</strong>m ser objecto <strong>de</strong> análise, e tabelas <strong>de</strong> dimensões, que armazenam os dados sobre as<br />

perspectivas segundo as quais os factos po<strong>de</strong>m ser analisados. Tanto as data warehouses como as<br />

operações OLAP são baseadas no mo<strong>de</strong>lo multidimensional, em que os dados são visualizados sob a<br />

forma <strong>de</strong> um cubo. Um cubo é <strong>de</strong>finido por um conjunto <strong>de</strong> dimensões e <strong>de</strong> factos. De uma forma<br />

genérica, as dimensões são as perspectivas ou entida<strong>de</strong>s em relação às quais os factos se referem.<br />

Por exemplo, uma empresa po<strong>de</strong> manter uma data warehouse <strong>de</strong> vendas como forma <strong>de</strong> manter<br />

registos sobre as suas vendas no que se refere aos itens vendidos, à filial em que foram vendidos e à<br />

data <strong>de</strong> venda. Cada dimensão po<strong>de</strong> estar associada a uma tabela que pormenoriza a sua <strong>de</strong>scrição. No<br />

13


exemplo anterior, a tabela <strong>de</strong> dimensão para os itens vendidos po<strong>de</strong> conter os atributos nome, categoria<br />

e marca. Quanto aos factos, estes são medidas numéricas correspon<strong>de</strong>ntes ao principal objectivo da<br />

data warehouse. Ainda no exemplo anterior, o número <strong>de</strong> unida<strong>de</strong>s vendidas ou o volume total <strong>de</strong><br />

vendas em dinheiro são factos possíveis para uma data warehouse <strong>de</strong> vendas.<br />

Ao contrário do sólido geométrico com o nome correspon<strong>de</strong>nte, em OLAP os cubos não são<br />

necessariamente tridimensionais mas sim n-dimensionais. A melhor forma <strong>de</strong> esclarecer este conceito<br />

passa por exemplificar o mesmo. Para tal, consi<strong>de</strong>re-se a tabela abaixo, que representa informação<br />

sobre as vendas <strong>de</strong> uma <strong>de</strong>terminada organização apresentada em função do tempo (Tempo) e do tipo<br />

<strong>de</strong> item vendido (Item).<br />

Tabela 1 <strong>–</strong> Volume <strong>de</strong> vendas em função do tempo e do tipo <strong>de</strong> item para a cida<strong>de</strong> <strong>de</strong> Vancouver [Han2001a]<br />

Tempo<br />

(trimestre)<br />

Vendas para todas as localizações em Vancouver<br />

Item (tipo)<br />

Entretenimento Computador Telefone Segurança<br />

Q1 605k 825k 14k 400k<br />

Q2 680k 952k 31k 512k<br />

Q3 812k 1023k 30k 501k<br />

Q4 927k 1038k 38k 580k<br />

No caso <strong>de</strong> preten<strong>de</strong>rmos visualizar a informação relativa às vendas não apenas em função do tempo e<br />

dos itens vendidos mas também em função da Localização em que a venda foi feita, seria necessário<br />

acrescentar à tabela acima uma terceira dimensão, obtendo-se assim uma série <strong>de</strong> tabelas diferentes 1 .<br />

Tabela 2 <strong>–</strong> Volume <strong>de</strong> vendas em função do tempo, tipo <strong>de</strong> item e localização [Han2001a]<br />

Tempo<br />

(trimestre)<br />

Entretenimento<br />

Localização = Vancouver<br />

Item<br />

Computador Telefone Segurança<br />

Q1 605k 825k 14k 400k<br />

Q2 680k 952k 31k 512k<br />

Q3 812k 1023k 30k 501k<br />

Q4 927k 1038k 38k 580k<br />

Tempo<br />

(trimestre)<br />

Entretenimento<br />

Localização = Montréal<br />

Item<br />

Computador Telefone Segurança<br />

Q1 818k 746k 43k 591k<br />

Q2 894k 769k 52k 682k<br />

Q3 940k 795k 58k 728k<br />

Q4 978k 864k 59k 784k<br />

1 Estas tabelas po<strong>de</strong>m ser representadas numa só pivot tabela, tal como se <strong>de</strong>screve mais adiante.<br />

14


Tempo<br />

(trimestre)<br />

Entretenimento<br />

Localização = New York<br />

Item<br />

Computador Telefone Segurança<br />

Q1 1087k 968k 38k 872k<br />

Q2 1130k 1024k 41k 925k<br />

Q3 1034k 1048k 45k 1002k<br />

Q4 1142k 1091k 54k 984k<br />

Tempo<br />

(trimestre)<br />

Entretenimento<br />

Localização = Chicago<br />

Item<br />

Computador Telefone Segurança<br />

Q1 854k 882k 89k 623k<br />

Q2 943k 890k 64k 698k<br />

Q3 1032k 924k 59k 789k<br />

Q4 1129k 992k 63k 870k<br />

As tabelas acima equivalem conceptualmente ao cubo 3D da figura abaixo.<br />

Figura 1 <strong>–</strong> Representação sob a forma <strong>de</strong> cubo 3D da tabela 2 [Han2001a]<br />

Supondo que se preten<strong>de</strong>sse adicionar outra dimensão, <strong>de</strong>signada como Fornecedor, à informação da<br />

tabela 1, obter-se-ia um cubo 4D, o que não é trivial <strong>de</strong> representar ou visualizar. Porém, po<strong>de</strong>mos<br />

consi<strong>de</strong>rar um cubo 4D como uma série <strong>de</strong> cubos 3D para cada uma das combinações possíveis das<br />

quatro dimensões três a três. Desta forma, qualquer informação n-dimensional po<strong>de</strong> ser representada<br />

sob a forma <strong>de</strong> uma série <strong>de</strong> cubos (n-1)-dimensionais. No fundo, o termo cubo é apenas uma metáfora<br />

para representar o carácter multidimensional dos dados.<br />

15


Dado um conjunto <strong>de</strong> dimensões, é possível construir uma malha <strong>de</strong> cubói<strong>de</strong>s em que cada um <strong>de</strong>les<br />

mostra os dados em diferentes níveis <strong>de</strong> sumarização ou agregação, isto, agrupados segundo diferentes<br />

subconjuntos das dimensões. Um cubo como o da figura 1 é normalmente <strong>de</strong>signado <strong>de</strong> cubói<strong>de</strong> base,<br />

enquanto o cubói<strong>de</strong> 0D, que apresenta o mais alto grau <strong>de</strong> sumarização possível, é o cubo ápice. Ao<br />

conjunto da malha <strong>de</strong> cubói<strong>de</strong>s dá-se o nome <strong>de</strong> cubo <strong>de</strong> dados (data cube).<br />

Figura 2 <strong>–</strong> Malha <strong>de</strong> cubói<strong>de</strong>s para um cubo 4D [Han2001a]<br />

O mo<strong>de</strong>lo multidimensional <strong>de</strong> dados po<strong>de</strong> ser implementado segundo um esquema em estrela, em floco<br />

<strong>de</strong> neve ou em constelação <strong>de</strong> factos. O esquema em estrela é o esquema mais usado para representar<br />

data warehouses, sendo composto por uma tabela central <strong>de</strong> factos e várias tabelas <strong>de</strong> dimensão<br />

ligadas à tabela central. O esquema em floco <strong>de</strong> neve é uma variante do esquema em estrela que, ao<br />

propor a normalização das tabelas relativas às dimensões, elimina alguns problemas <strong>de</strong> redundância<br />

<strong>de</strong>vidos ao facto <strong>de</strong> cada dimensão correspon<strong>de</strong>r a uma única tabela no esquema em estrela. A nível<br />

arquitectural, as data warehouses po<strong>de</strong>m ser implementadas sobre sistemas <strong>de</strong> gestão <strong>de</strong> bases <strong>de</strong><br />

dados relacionais, <strong>de</strong>signados como servidores relacionais (servidores ROLAP) e que suportam métodos<br />

especiais que lhes permitem implementar o mo<strong>de</strong>lo multidimensional e as operações sobre ele. Outra<br />

arquitectura possível para as data warehouses assenta em servidores multidimensionais (servidores<br />

MOLAP), que recorrem a estruturas <strong>de</strong> dados apropriadas para implementar o mo<strong>de</strong>lo multidimensional<br />

e as operações necessárias.<br />

Para tirar partido da flexibilida<strong>de</strong> proporcionada pelo mo<strong>de</strong>lo multidimensional, existem várias operações<br />

que po<strong>de</strong>m ser realizadas sobre o cubo e permitem obter diferentes vistas dos dados. Para a <strong>de</strong>scrição<br />

das operações mais comuns, consi<strong>de</strong>re-se o mo<strong>de</strong>lo multidimensional representado na figura 3.<br />

16


Figura 3 <strong>–</strong> Exemplo <strong>de</strong> um mo<strong>de</strong>lo multidimensional [Chanduri1997]<br />

A operação <strong>de</strong> roll-up permite realizar agregações ao subir na hierarquia <strong>de</strong> uma dimensão. Tomando a<br />

dimensão Cida<strong>de</strong> <strong>de</strong>finida na figura 3, um exemplo <strong>de</strong> uma operação <strong>de</strong> roll-up será aquela que agrega<br />

os dados subindo na hierarquia do nível cida<strong>de</strong> para o nível país. Este tipo <strong>de</strong> operação po<strong>de</strong> também<br />

ser conseguida através da remoção <strong>de</strong> dimensões, que na prática tem o mesmo efeito <strong>de</strong> agregação dos<br />

dados em torno das dimensões que não são removidas.<br />

A operação <strong>de</strong> drill-down é inversa à operação <strong>de</strong> roll-up, permitindo passar <strong>de</strong> um nível <strong>de</strong> menor<br />

<strong>de</strong>talhe para um nível <strong>de</strong> maior <strong>de</strong>talhe.Tomando a dimensão Produto na figura 3, um exemplo <strong>de</strong> uma<br />

operação <strong>de</strong> drill-down seria aquela em que se passasse do nível <strong>de</strong> trimestre para o nível <strong>de</strong> mês. À<br />

semelhança do que se verifica para a operação <strong>de</strong> roll-up, a operação <strong>de</strong> drill-down po<strong>de</strong> ser conseguida<br />

adicionando dimensões ao cubo, no sentido do maior <strong>de</strong>talhe permitido pela operação.<br />

As operações <strong>de</strong> slice e dice correspon<strong>de</strong>m a acções <strong>de</strong> selecção por parte do utilizador. Enquanto a<br />

primeira correspon<strong>de</strong> à selecção <strong>de</strong> dados do cubo tendo em conta apenas uma dimensão, a segunda<br />

correspon<strong>de</strong> à selecção <strong>de</strong> dados por mais que uma dimensão. O resultado <strong>de</strong> qualquer uma das<br />

operações é o subcubo correspon<strong>de</strong>nte aos critérios enumerados. No exemplo dado na figura 3, é<br />

possível fazer slice e dice aos dados <strong>de</strong> modo a obter uma tabela que apenas contém os valores<br />

referentes à dimensão cida<strong>de</strong> e ao dia <strong>de</strong> venda <strong>de</strong> um <strong>de</strong>terminado produto.<br />

A operação <strong>de</strong> pivoting é uma técnica <strong>de</strong> visualização em que os eixos do cubo são rodados <strong>de</strong> forma a<br />

possibilitar outra perspectiva dos dados. O significado <strong>de</strong>sta operação é melhor entendido se se<br />

visualizar o mo<strong>de</strong>lo multidimensional da figura 3 representado numa folha <strong>de</strong> cálculo em que cada linha<br />

correspon<strong>de</strong> a uma venda, representando cada coluna uma dimensão e a última coluna o valor da venda<br />

[Chanduri1997]. O valor contido em cada célula representa o valor agregado <strong>de</strong> uma <strong>de</strong>terminada<br />

medida (neste caso, o valor <strong>de</strong> vendas) quando a primeira dimensão tem o valor x e a segunda<br />

dimensão tem o valor y. Seguindo o exemplo da figura 3 e assumindo que consi<strong>de</strong>ramos apenas as<br />

dimensões cida<strong>de</strong> e ano, então o eixo x representa todos os valores possíveis <strong>de</strong> cida<strong>de</strong> e o eixo y<br />

representa todos os valores possíveis <strong>de</strong> ano. Consequentemente, o ponto (x, y) representa o valor<br />

agregado <strong>de</strong> vendas para a cida<strong>de</strong> x no ano y. A operação <strong>de</strong> pivoting permite trocar os eixos x e y, o<br />

17


que faria com que cada ponto (x, y) passasse a representar o valor agregado <strong>de</strong> vendas para o ano x na<br />

cida<strong>de</strong> y.<br />

Além das mencionadas acima, existem outras operações OLAP oferecidas em sistemas comerciais, tais<br />

como o drill-through ou o drill-cross, que resultam da combinação <strong>de</strong> algumas das operações anteriores.<br />

2.2 O operador DATA CUBE<br />

Os utilizadores típicos <strong>de</strong> sistemas <strong>de</strong> apoio à <strong>de</strong>cisão estão mais interessados em extrair informação<br />

dos dados do que propriamente em visualizá-los, o que faz com que as interrogações que realizam<br />

exijam agregação dos dados, na maior parte dos casos sobre várias dimensões. O uso das funções <strong>de</strong><br />

agregação existentes no SQL (group-by e union) traz alguns problemas que serviram <strong>de</strong> motivação para<br />

a concepção do operador DATA CUBE, <strong>de</strong>stacando-se <strong>de</strong>sses problemas o cálculo <strong>de</strong> totais para<br />

operações <strong>de</strong> roll-up e <strong>de</strong> subtotais para operações <strong>de</strong> drill-down. A apresentação <strong>de</strong> resultados sob a<br />

forma <strong>de</strong> cross-tables, que são tabelas que expressam a relação entre os valores apresentados nas<br />

linhas e os valores apresentados nas colunas, também não é facilitada recorrendo às funções <strong>de</strong><br />

agregação nativas <strong>de</strong> SQL, uma vez que estas tabelas mostram o resultado <strong>de</strong> várias operações, como<br />

o total, o total das colunas e o total das linhas [Gray1997]. A tabela 3 mostra uma organização típica dos<br />

dados numa aplicação OLAP, em que os agregados são cada vez mais finos e em cada nível é gerado<br />

um subtotal.<br />

Tabela 3 <strong>–</strong> Roll-up das vendas por mo<strong>de</strong>lo, ano e cor adaptado <strong>de</strong> [Gray1997]<br />

Marca Ano Cor<br />

Vendas<br />

por mo<strong>de</strong>lo<br />

por ano por cor<br />

Chevy 1994 Preto 50<br />

Branco 40<br />

1995 Preto 85<br />

Branco 115<br />

Vendas<br />

por mo<strong>de</strong>lo<br />

por ano<br />

90<br />

Vendas<br />

por<br />

mo<strong>de</strong>lo<br />

Porém, a representação <strong>de</strong>sta tabela não é relacional visto que existem células vazias, inviabilizando<br />

assim a hipótese <strong>de</strong> funcionarem como i<strong>de</strong>ntificadores unívocos (chaves). Para obviar este problema,<br />

Chris Date recomendou a criação <strong>de</strong> 2 n colunas <strong>de</strong> agregação para um roll-up <strong>de</strong> n elementos<br />

[Gray1997], obtendo-se assim a tabela 4.<br />

200<br />

290<br />

18


Tabela 4 - Roll-up das vendas por mo<strong>de</strong>lo, ano e cor como sugerido por Chris Date, adaptado <strong>de</strong> [Gray1997]<br />

Mo<strong>de</strong>lo Ano Cor Unida<strong>de</strong>s<br />

Chevy 1994 Preto 50<br />

Chevy 1994 Branco 40<br />

Chevy 1994 ALL 90<br />

Chevy 1995 Preto 85<br />

Chevy 1995 Branco 115<br />

Chevy 1995 ALL 200<br />

Chevy ALL ALL 290<br />

Esta alternativa, apesar <strong>de</strong> elegante, aumenta significativamente o número <strong>de</strong> células a calcular quando<br />

o número <strong>de</strong> dimensões aumenta ligeiramente. Para evitar o crescimento exagerado das tabelas <strong>de</strong>vido<br />

à adição das novas colunas, os autores propuseram a re<strong>de</strong>finição dos valores das colunas, introduzindo<br />

o valor ALL. Cada valor ALL representa um conjunto <strong>de</strong> dados sobre o qual já foi computado o valor da<br />

agregação. A tabela 5 mostra o resultado da aplicação <strong>de</strong>sta representação.<br />

Tabela 5 - Resultado após computada a agregação, adaptado <strong>de</strong> [Gray1997]<br />

Marca Ano Cor Vendas Vendas<br />

Por mo<strong>de</strong>lo<br />

Por ano<br />

Vendas<br />

Por<br />

mo<strong>de</strong>lo<br />

Chevy 1994 Preto 50 90 290<br />

Chevy 1994 Branco 40 90 290<br />

Chevy 1995 Preto 85 200 290<br />

Chevy 1995 Branco 115 200 290<br />

Desta forma, a tabela representa uma relação e é possível obtê-la recorrendo a SQL standard,<br />

efectuando tantas uniões quantas as dimensões a serem consi<strong>de</strong>radas. Porém, como a operação <strong>de</strong> roll-<br />

up é simétrica, a tabela anterior necessita <strong>de</strong> ser acrescentada com a tabela 6 para que passe a<br />

representar um cubo.<br />

Tabela 6 - Linhas a acrescentar à tabela 3 adaptado <strong>de</strong> [Gray1997]<br />

Mo<strong>de</strong>lo Ano Cor Unida<strong>de</strong>s<br />

Chevy ALL Preto 135<br />

Chevy ALL Branco 135<br />

As linhas constantes da tabela 6 po<strong>de</strong>m ser obtidas adicionando uma união à instrução <strong>de</strong> SQL a partir<br />

da qual se obteve a tabela 5. O resultado <strong>de</strong>sta junção permite que a operação <strong>de</strong> roll-up seja simétrica e<br />

gera a tabela 7, a que se dá o nome <strong>de</strong> cross tab.<br />

19


Tabela 7 - Cross table para as vendas da marca Chevy adaptado <strong>de</strong> [Gray1997]<br />

Chevy 1994 1995 Total (ALL)<br />

Chevy ALL Preto 135<br />

Chevy ALL Branco 155<br />

Total (ALL) 90 200 290<br />

Esta pequena <strong>de</strong>monstração é suficiente para mostrar que, apesar do uso <strong>de</strong> group-by e union resolver o<br />

problema <strong>de</strong> calcular os agregados, a forma como isso é conseguido não é eficiente em termos <strong>de</strong><br />

tempo e gera representações <strong>de</strong> díficil análise. Com efeito, exprimir histogramas, roll-ups, drill-downs e<br />

cross tables recorrendo a SQL convencional não é imediato e trivial: uma cross table 6D requer a<br />

realização da operação union <strong>de</strong> 64 formas diferentes para 64 group-bys diferentes e continua a não ser<br />

realmente um objecto relacional [Gray1997].<br />

Em 1996, Gray et al propuseram o operador DATA CUBE ou, mais simplemente, CUBE, capaz <strong>de</strong><br />

computar agregados sobre todas as combinações possíveis <strong>de</strong> atributos para um conjunto <strong>de</strong><br />

dimensões. Basicamente, o operador CUBE é uma generalização n-dimensional das funções <strong>de</strong><br />

agregação básicas <strong>de</strong> SQL, tal como mostra a figura 4 [Gray1997].<br />

Figura 4 - Operador CUBE para cubos 0D, 1D, 2D e 3D [Gray1997]<br />

20


O cubo 0D (em cima à esquerda na figura 4) refere-se ao agregado vazio e correspon<strong>de</strong> à soma total <strong>de</strong><br />

todos os valores. Graficamente, o cubo 1D (em cima no centro da figura 4) tem o aspecto <strong>de</strong> uma linha e<br />

um ponto, na medida em que contém todos os valores agregados por um atributo e o resultado da soma<br />

<strong>de</strong> todos esses valores; na figura 2, correspon<strong>de</strong> ao agregado segundo o atributo cor. Por sua vez, o<br />

cubo 2D (em cima à direita na figura 4) correspon<strong>de</strong> a um plano, duas linhas e um ponto, ou seja, a uma<br />

cross-table com duas colunas e respectivos totais por linha e por coluna. Tal como mostra a figura 4, faz-<br />

se a agregação segundo dois atributos, que são marca e cor. Por fim, um cubo 3D (em baixo na figura 4)<br />

equivale à intersecção <strong>de</strong> três cross tables, correspon<strong>de</strong>ndo cada uma <strong>de</strong>las à agregação por diferentes<br />

grupos <strong>de</strong> atributos.<br />

Este novo operador surgiu como forma <strong>de</strong> ultrapassar as limitações <strong>de</strong>monstradas pelo uso <strong>de</strong> SQL. O<br />

trabalho apresentado foi posteriormente consi<strong>de</strong>rado tão relevante que foi mesmo realizada uma<br />

implementação <strong>de</strong>sse operador, com algumas alterações, em SQL, tal como referido em [Zhao1997].<br />

2.3 Selecção <strong>de</strong> agregados para pré-computação<br />

Tipicamente, os sistemas <strong>de</strong> apoio à <strong>de</strong>cisão <strong>de</strong>vem ser capazes <strong>de</strong> lidar com interrogações complexas<br />

sobre bases <strong>de</strong> dados <strong>de</strong> gran<strong>de</strong> dimensão e <strong>de</strong>volver respostas em tempos curtos, o que faz com que a<br />

optimização <strong>de</strong> interrogações seja fundamental. Tendo em conta que, neste contexto, os dados<br />

normalmente são vistos sob a forma do mo<strong>de</strong>lo multidimensional, uma das técnicas mais usadas neste<br />

sentido é a pré-computação <strong>de</strong> alguns agregados por forma a evitar a repetição <strong>de</strong>ste cálculo. Este<br />

problema da eficiência no cálculo <strong>de</strong> cubos foi estudado por Harinarayan et al, que propuseram uma<br />

plataforma para escolher quais os agregados que <strong>de</strong>vem ser calculados previamente [Harinarayan1996].<br />

Num cubo, existem várias células cujos valores são obtidos a partir <strong>de</strong> outras células. Assumindo que<br />

cada célula é representada por uma lista <strong>de</strong> valores relativos a cada uma das dimensões que a<br />

compõem, qualquer célula que tenha o valor ALL como um dos seus componentes <strong>de</strong>pen<strong>de</strong> <strong>de</strong> outra<br />

célula. Qualquer célula cuja composição não inclua o valor ALL po<strong>de</strong> ser obtida a partir da tabela <strong>de</strong><br />

dados. No seu trabalho, Harinarayan et al utilizaram uma base <strong>de</strong> dados com três atributos: peça (P),<br />

fornecedor (S) e cliente (C). Assim sendo, existem 2 3 conjugações possíveis <strong>de</strong>sses atributos: (peça,<br />

fornecedor, cliente), (peça, cliente), (peça, fornecedor), (fornecedor, cliente), (peça), (fornecedor),<br />

(cliente) e ( ). A última conjugação expressa o caso em que não são especificados atributos, o que<br />

significa que, num cubo com n dimensões, existem 2 n possíveis operações <strong>de</strong> agregação. A<br />

representação em malha na figura 5 mostra as relações entre as várias conjugações possíveis <strong>de</strong><br />

atributos.<br />

21


Figura 5 - Malha <strong>de</strong> combinações possíveis para 3 atributos [Harinarayan1996]<br />

Consi<strong>de</strong>rando duas interrogações Q1 e Q2, diz-se que Q1 <strong>de</strong>pen<strong>de</strong> <strong>de</strong> Q2 se Q1 po<strong>de</strong> ser respondida<br />

usando apenas os resultados <strong>de</strong> Q2. Tomando a figura 5, a interrogação (peça) po<strong>de</strong> ser respondida<br />

usando os resultados da interrogação (peça, cliente); logo, a interrogação (peça) <strong>de</strong>pen<strong>de</strong> da<br />

interrogação (peça, cliente).<br />

Este trabalho introduziu também o mo<strong>de</strong>lo <strong>de</strong> custo linear (linear cost mo<strong>de</strong>l) para exprimir o custo <strong>de</strong><br />

uma <strong>de</strong>terminada interrogação. Segundo este mo<strong>de</strong>lo, o tempo necessário para respon<strong>de</strong>r a uma<br />

interrogação Q correspon<strong>de</strong> ao número <strong>de</strong> linhas existentes na tabela <strong>de</strong> dados e que são necessárias<br />

para respon<strong>de</strong>r à interrogação QA, previamente respondida e da qual a interrogação Q <strong>de</strong>pen<strong>de</strong>.<br />

2.4 Computação <strong>de</strong> agregados multidimensionais<br />

Tal como foi referido, a tarefa <strong>de</strong> computar um cubo correspon<strong>de</strong>, basicamente, a pré-computar e<br />

armazenar agregações <strong>de</strong> dados multidimensionais <strong>de</strong> maneira a que seja possível analisar<br />

imediatamente esses dados. Naturalmente, esta é uma tarefa que consome bastantes recursos a nível<br />

<strong>de</strong> tempo e espaço. Logo, o <strong>de</strong>sempenho é uma questão fulcral no que se refere à computação e<br />

representação do cubo, tendo sido <strong>de</strong>senvolvidos vários algoritmos para esta tarefa.<br />

Segundo [Gray1997], as funções <strong>de</strong> agregação po<strong>de</strong>m ser classificados em três categorias:<br />

Funções distributivas <strong>–</strong> a função F( ) é consi<strong>de</strong>rada distributiva se existir uma função G( ) tal que<br />

F({Xi,j}) = G({F({Xi,j | i = 1, ..., I}) |j = 1, ..., J}); como exemplos, temos as funções COUNT( ),<br />

MIN( ), MAX( ) e SUM( ).<br />

Funções algébricas <strong>–</strong> a função F( ) é consi<strong>de</strong>rada algébrica se existir um tuplo <strong>de</strong> or<strong>de</strong>m M <strong>de</strong><br />

valores <strong>de</strong> uma função G( ) e uma função H( ) tal que F({Xi,j}) = H({G({Xi,j | i = 1, ..., I}) | j = 1, ...,<br />

J}); como exemplos, temos a função AVG().<br />

Funções holísticas <strong>–</strong> uma função F( ) é consi<strong>de</strong>rada holística se não existir uma constante M tal<br />

que caracterize a computação F({Xi,j | i = 1, ..., I}); como exemplo, temos a mediana ou a moda.<br />

No que se refere às funções holísticas, a forma mais eficiente <strong>de</strong> computar agregados <strong>de</strong>ste tipo <strong>de</strong><br />

funções é o recurso ao algoritmo 2 N [Gray1997]. Este algoritmo começa por reservar um apontador<br />

22


Para isso, foram estudados dois métodos básicos para computação <strong>de</strong> um único agregado: um <strong>de</strong>les é<br />

baseado em or<strong>de</strong>namento (PipeSort) e outro é baseado em dispersão (PipeHash) [Agrawal1996]. Estes<br />

métodos po<strong>de</strong>m ser aplicados à computação <strong>de</strong> múltiplos agregados recorrendo às seguintes<br />

optimizações:<br />

Pais mais pequenos (smallest-parents) <strong>–</strong> consiste em computar um agregado a partir <strong>de</strong> outros<br />

<strong>de</strong> menor dimensão já computados.<br />

Resultados em cache (cache-results) <strong>–</strong> consiste em manter em memória os resultados <strong>de</strong> um<br />

agregado a partir do qual seja possível calcular outros, por forma a evitar as operações <strong>de</strong><br />

entrada e saída.<br />

Amortização <strong>de</strong> varrimentos (amortize-scans) <strong>–</strong> trata-se <strong>de</strong> amortizar o número <strong>de</strong> operações <strong>de</strong><br />

leitura do disco ao computar o maior número <strong>de</strong> agregados que for possível manter em memória.<br />

Partilha da or<strong>de</strong>nação (share-sorts) <strong>–</strong> apenas se aplica a algoritmos baseados em or<strong>de</strong>nação e<br />

aposta na partilha dos custos associados à or<strong>de</strong>nação por vários agregados.<br />

Partilha <strong>de</strong> partições (share-partitions) <strong>–</strong> apenas se aplica a algoritmos que utilizem dispersão e<br />

refere-se à partição da tabela <strong>de</strong> dispersão, caso seja <strong>de</strong>masiado gran<strong>de</strong> para os recursos <strong>de</strong><br />

memória disponíveis, e a efectuar a agregação apenas para cada uma das partições.<br />

Tanto PipeSort como PipeHash computam vários agregados segundo uma lógica sequencial, sendo<br />

cada fio <strong>de</strong> computação constituído por agregados que po<strong>de</strong>m ser computados pelo mesmo varrimento<br />

dos dados <strong>de</strong> entrada. De forma a estabelecer quais os agregados que po<strong>de</strong>m ser computados a partir<br />

<strong>de</strong> outros e qual a sequência pela qual os atributos <strong>de</strong>vem ser tratados, foi utilizado o conceito <strong>de</strong> malha<br />

<strong>de</strong> procura apresentado em [Harinarayan1996].<br />

Basicamente, uma malha <strong>de</strong> procura é um grafo em que cada nó representa um agregado do cubo.<br />

Quando um nó i está ligado a um nó j, isso significa que o agregado j po<strong>de</strong> ser gerado a partir do<br />

agregado i e que j tem exactamente um atributo a menos que i [Agrawal1996]. A figura 7 apresenta um<br />

exemplo <strong>de</strong> uma malha <strong>de</strong> procura para quatro atributos (A, B, C e D), em que cada nível k reúne os<br />

agregados que contêm exactamente k atributos.<br />

Figura 7 - Exemplo <strong>de</strong> uma malha <strong>de</strong> procura [Agrawal1996]<br />

24


Por exemplo, no nível 2 da malha todos os agregados contêm exactamente dois atributos. A única<br />

excepção a esta regra é o nível 0, que apenas contém um agregado vazio e é representado pelo termo<br />

ALL. Cada arco da malha está etiquetado com dois custos: o custo S(eij) correspon<strong>de</strong> ao custo <strong>de</strong><br />

computar j a partir <strong>de</strong> i quando i ainda não está or<strong>de</strong>nado, enquanto o custo A(eij) correspon<strong>de</strong> ao custo<br />

<strong>de</strong> computar j a partir <strong>de</strong> i quando i já está or<strong>de</strong>nado [Agrawal1996].<br />

2.4.1.1 PipeSort<br />

O algoritmo PipeSort parte da malha <strong>de</strong> procura com os respectivos custos associados e assume que se<br />

conhece uma estimativa do número <strong>de</strong> valores distintos associados a cada agregado. A malha é<br />

percorrida <strong>de</strong>s<strong>de</strong> o nível k = 0 até ao nível k = N - 1, sendo N o número total <strong>de</strong> atributos, com o objectivo<br />

<strong>de</strong> <strong>de</strong>terminar a melhor forma <strong>de</strong> computar o nível k a partir do nível k + 1. Para isso, é acrescentado ao<br />

nível k + 1 k cópias <strong>de</strong> cada agregado nesse nível e cada nó replicado é ligado ao mesmo conjunto <strong>de</strong><br />

nós a que está ligado o vértice original na malha [Agrawal1996]. A figura 8 mostra este procedimento,<br />

consi<strong>de</strong>rando que se trabalha sobre o nível 1 da malha apresentada na figura 7. As setas em traço cheio<br />

representam os arcos A( ), enquanto as setas a tracejado representam os arcos S( ), sendo o custo <strong>de</strong><br />

todos os arcos que saem <strong>de</strong> um nó indicados sob eles.<br />

Figura 8 - Parte da malha <strong>de</strong> procura transformada [Agrawal1996]<br />

Sabendo que o custo eij <strong>de</strong>s<strong>de</strong> o nó original i até ao nó j <strong>de</strong> nível k é A(eij) e que todos os nós replicados<br />

<strong>de</strong> i têm um custo <strong>de</strong> S(eij), é possível encontrar, para cada nó h no nível k, um vértice g no nível k + 1 a<br />

partir do qual h po<strong>de</strong> ser calculado. Como se po<strong>de</strong> ver na figura 20, o nó A fica ligado ao nó AB por um<br />

arco S( ) e o nó B está ligado a AB por um arco A( ). No nível k = 2, o agregado AB será computado pela<br />

or<strong>de</strong>m BA para que B possa ser obtido a partir <strong>de</strong>le sem necessida<strong>de</strong> <strong>de</strong> reor<strong>de</strong>nação e A seja obtido<br />

reor<strong>de</strong>nando BA. Da mesma forma, como o nó C está ligado ao nó AC por um arco A( ), o nó AC será<br />

computado pela or<strong>de</strong>m CA. Quanto ao nó BC, como não está ligado a nenhum agregado <strong>de</strong> nível 1, é<br />

indiferente a or<strong>de</strong>m pela qual é calculado.<br />

Figura 9 - Resultado obtido pelo algoritmo PipeSort para k = 1 [Agrawal1996]<br />

25


Seguidamente, é feita uma or<strong>de</strong>nação com base no sub-grafo gerado e é obtido um conjunto <strong>de</strong><br />

sequências <strong>de</strong> agregados a serem computadas em sequência (pipeline).<br />

Este algoritmo concilia as optimizações partilha da or<strong>de</strong>nação (share-sort), uma vez que os dados são<br />

or<strong>de</strong>nados numa <strong>de</strong>terminada or<strong>de</strong>m que permita computar todos os agregados que partilham um<br />

prefixo, e pais mais pequenos (smallest parents), uma vez que os agregados são sempre calculados a<br />

partir <strong>de</strong> outros agregados <strong>de</strong> menor dimensão já calculados. Além disso, emprega ainda as<br />

optimizações resultados em cache (cache-results) e amortização <strong>de</strong> varrimentos (amortize-scans) para<br />

reduzir o número <strong>de</strong> acessos ao disco, pois adopta uma política <strong>de</strong> cálculo em pipeline.<br />

2.4.1.2 PipeHash<br />

O algoritmo PipeSort trabalha igualmente sobre a malha <strong>de</strong> procura e começa por escolher, para cada<br />

agregado, o seu pre<strong>de</strong>cessor <strong>de</strong> menor dimensão, obtendo assim a árvore <strong>de</strong> custo mínimo. Porém, os<br />

recursos normalmente disponíveis continuam a não ser suficientes para computar todos os agregados<br />

<strong>de</strong>ssa árvore, pelo que é necessário <strong>de</strong>cidir quais serão computados em conjunto, quando reservar<br />

memória para diferentes tabelas <strong>de</strong> dispersão e que atributos serão usados para dividir os dados<br />

[Agrawal1996].<br />

O algoritmo começa por seleccionar para, cada agregado, o agregado-pai com menor dimensão total<br />

estimada. No final, obtém uma árvore <strong>de</strong> cobertura mínima (minimum spanning tree), em que cada nó<br />

representa um agregado e cada arco que une o nó A ao nó B indica que A é o menor pai <strong>de</strong> B. A figura<br />

abaixo apresenta a árvore <strong>de</strong> cobertura mínima para a malha <strong>de</strong> procura apresentada na figura 7.<br />

Figura 10 - Árvore <strong>de</strong> cobertura mínima para a malha <strong>de</strong> procura apresentada na figura 7 [Agrawal1996]<br />

Na maioria dos casos, a memória disponível não será suficiente para calcular todos os agregados da<br />

árvore, pelo que é necessário dividir a árvore assim obtida. A árvore é dividida <strong>de</strong> tal forma que cada<br />

uma das sub-árvores obtidas possa ser calculada com uma única passagem do agregado na raiz da<br />

árvore original. Este é um problema NP-completo, o que obriga a escolher uma aproximação à solução;<br />

26


neste caso, o critério consiste em escolher para efectuar a partição o atributo que permita obter a maior<br />

sub-árvore possível a partir da árvore <strong>de</strong> custo mínimo.<br />

Tomando a árvore <strong>de</strong> cobertura mínima da figura 10 e assumindo que não há espaço em memória para<br />

calcular todos os agregados nela representados, há que efectuar a partição da árvore. Quando A é<br />

escolhido como atributo pelo qual se vai efectuar a partição, obtém-se a sub-árvore à esquerda na figura<br />

22. Para computar esta árvore, calcula-se primeiro o agregado ABCD e a partir <strong>de</strong>ste ABC, ABD e ACD;<br />

ABCD e ABD são guardados em disco, calcula-se AD a partir <strong>de</strong> ACD e ACD e AD são guardados em<br />

disco; ABC é lido para a partir <strong>de</strong>le se calcular AB e AC, sendo ABC e AC guardados em disco; por fim,<br />

AB é lido para calcular A e AB e A são guardados em disco. Depois <strong>de</strong>sta sub-árvore ter sido calculada,<br />

é removida da árvore original e são calculadas cada uma das sub-árvores restantes, à direita na figura<br />

11.<br />

Figura 11 - Sub-árvores obtidas por partição da árvore da figura 10 segundo o atributo A [Agrawal1996]<br />

Este algoritmo emprega as optimizações resultados em cache (cache-results) e amortização <strong>de</strong><br />

varrimentos (amortize-scans), pois mantém em memória todos os agregados <strong>de</strong> uma sub-árvore até que<br />

os seus filhos tenham sido calculados, assim como a optimização partilha <strong>de</strong> partições (share-partition)<br />

ao conseguir calcular a partir da mesma partição todos os agregados que contêm o atributo pelo qual se<br />

fez a partição.<br />

2.4.2 Algoritmos baseados em partição<br />

Os dados provenientes do mundo real são frequentemente <strong>de</strong> natureza esparsa, o que justifica o estudo<br />

e <strong>de</strong>senvolvimento <strong>de</strong> técnicas orientadas para esse tipo <strong>de</strong> dados. Nestas condições, a representação<br />

por meio <strong>de</strong> arrays não é uma hipótese viável visto que não é comportável em termos <strong>de</strong> memória. Os<br />

algoritmos baseados na partição dos dados usam dois princípios a que se recorre frequentemente para<br />

realizar operações complexas sobre relações amplas: efectuar a partição das relações em fragmentos<br />

que possam ser armazenados em memória e efectuar a operação sobre cada um <strong>de</strong>sses fragmentos<br />

in<strong>de</strong>pen<strong>de</strong>ntemente. Existem dois algoritmos para computação <strong>de</strong> cubos a partir <strong>de</strong> dados esparsos:<br />

27


Partitioned-Cube e Memory-Cube [Ross1997]. O algoritmo Memory-Cube foi concebido para computar<br />

eficientemente os cubos cujas relações possam ser mantidas em memória, enquanto o algoritmo<br />

Partitioned-Cube basicamente efectua a partição da relação e recorre ao Memory-Cube para computar<br />

as partições assim obtidas.<br />

A estrutura do algoritmo Partitioned-Cube segue a própria estrutura recursiva dos cubos. O cubo é obtido<br />

fixando cada um dos valores possíveis para um atributo e calculando os tuplos <strong>de</strong>sse sub-cubo. Em<br />

seguida calculam-se todos os tuplos do cubo que têm como valor para esse atributo ALL. Desta forma,<br />

em vez <strong>de</strong> voltar a ler os dados para calcular o cubo ALL, apenas é necessário ler o cubói<strong>de</strong> <strong>de</strong><br />

granularida<strong>de</strong> mais fina, que po<strong>de</strong> ser bastante menor que a relação que representa e nunca é maior que<br />

essa relação [Ross1997]. O algoritmo divi<strong>de</strong> o cubo em n + 1 subcubos mais pequenos, o que faz com<br />

que esses subcubos possam ser calculados em memória recorrendo ao algoritmo Memory-Cube.<br />

Consi<strong>de</strong>rando uma relação que possui quatro atributos or<strong>de</strong>nados como (A, B, C, D), o algoritmo<br />

proce<strong>de</strong> à partição dos dados tomando os atributos por essa or<strong>de</strong>m e calcula os cubói<strong>de</strong>s respectivos<br />

sempre que o resultado <strong>de</strong> cada partição possa ser guardado em memória. Assim, a relação em causa<br />

começa por ser dividida pelo atributo A, sendo computados os tuplos possíveis para cada um dos<br />

cubói<strong>de</strong>s que contêm A como atributo. Seguidamente, a relação é dividida pelo atributo B, sendo<br />

projectado o atributo A, e o procedimento é repetido, o que faz com que sejam computados todos os<br />

tuplos dos cubói<strong>de</strong>s que contêm B. A partição continua enquanto não se verificar que os cubói<strong>de</strong>s<br />

restantes po<strong>de</strong>m ser calculados em memória, embora o algoritmo não especifique exactamente como<br />

realizar a divisão. A figura 12 mostra a or<strong>de</strong>m pela qual o algoritmo calcula os vários cubói<strong>de</strong>s sempre<br />

que o resultado da partição cabe em memória.<br />

Figura 12 - Ilustração da lógica do funcionamento do algoritmo Partitioned-Cube [Ross1997]<br />

O algoritmo Memory-Cube foi <strong>de</strong>senvolvido para o caso em que toda a relação em estudo po<strong>de</strong> ser<br />

mantida em memória. Apesar <strong>de</strong> ser um bloco constituinte do algoritmo Partitioned-Cube, po<strong>de</strong> funcionar<br />

<strong>de</strong> forma in<strong>de</strong>pen<strong>de</strong>nte uma vez que é capaz <strong>de</strong> computar um cubo por completo sem necessida<strong>de</strong> <strong>de</strong><br />

guardar resultados intermédios. Essa característica permite-lhe operar requerendo apenas alguma<br />

capacida<strong>de</strong> <strong>de</strong> armazenamento extra além da que é utilizada pela relação. Basicamente, usa o conceito<br />

28


<strong>de</strong> malha <strong>de</strong> procura proposto pelo algoritmo PipeSort, a partir da qual <strong>de</strong>termina quais os cubói<strong>de</strong>s que<br />

po<strong>de</strong>m ser obtidos a partir <strong>de</strong> outros no sentido <strong>de</strong> minimizar o número <strong>de</strong> caminhos que é necessário<br />

percorrer para cobrir todos os nós. Assim, para cada cubo o algoritmo toma um caminho e or<strong>de</strong>na a<br />

relação em memória tendo em conta a or<strong>de</strong>nação dos atributos no nó inicial. Seguidamente, os dados<br />

são percorridos, sendo os agregados acumulados à medida que o caminho percorre os vários níveis <strong>de</strong><br />

granularida<strong>de</strong>.<br />

Os resultados mostram que o algoritmo faz o número mínimo possível <strong>de</strong> or<strong>de</strong>nações e consegue tirar<br />

partido dos prefixos comuns <strong>de</strong> diferentes agregados <strong>de</strong> forma a optimizar o custo a nível <strong>de</strong><br />

processamento. Além disso, os únicos custos <strong>de</strong> entrada/saída inerentes são os <strong>de</strong> entrada <strong>de</strong> dados e<br />

saída dos resultados, o que faz com que a carga total <strong>de</strong>ste tipo <strong>de</strong> operações seja linear em relação ao<br />

número <strong>de</strong> atributos envolvidos, sempre que a relação possa estar em memória.<br />

2.4.3 Algoritmos baseados em arrays<br />

Nos sistemas do tipo MOLAP, os dados são armazenados em arrays, o que faz com que as técnicas do<br />

tipo or<strong>de</strong>nação e dispersão não sejam aplicáveis. O próprio facto <strong>de</strong> ser utilizado outro tipo <strong>de</strong> estrutura<br />

<strong>de</strong> dados faz com que seja necessário ter em conta uma série <strong>de</strong> factores relacionados com o<br />

carregamento e armazenamento eficientes <strong>de</strong> arrays <strong>de</strong> gran<strong>de</strong>s dimensões e muito esparsos.<br />

O algoritmo Multi-Way Array Cubing, proposto por Zhao et al segue os princípios do paradigma MOLAP<br />

na medida em que o seu objectivo é percorrer as células dos arrays <strong>de</strong> tal forma que não seja necessário<br />

repetir a operação para calcular cada um dos sub-agregados. Por questões <strong>de</strong> <strong>de</strong>sempenho, os arrays<br />

têm que ser armazenados divididos em arrays <strong>de</strong> menor dimensão, recorrendo-se a uma estratégia<br />

<strong>de</strong>signada <strong>de</strong> chunking [Zhao1997].<br />

DS fonte <strong>de</strong> dados<br />

c chunk<br />

chunkSize tamanho do chunk<br />

O {D 1,D 2,...,D n : |D 1|≤|D 2|≤...≤|D n|}<br />

T MMST para or<strong>de</strong>m O<br />

m número <strong>de</strong> elementos <strong>de</strong> O<br />

para cada c no nivel m do array<br />

carregar dados para c a partir <strong>de</strong> DS<br />

i n<br />

para cada D i<br />

para cada posição <strong>de</strong> c<br />

val valor da posição<br />

fazer<br />

nextLevel m-1<br />

para cada nó em nextLevel<br />

remover posição não utilizada em nó<br />

agregar valor no nó<br />

até<br />

nextLevel≥0<br />

i i-1<br />

Figura 13 <strong>–</strong> Pseudocódigo genérico do algoritmo Multi-Way<br />

29


A técnica tradicional <strong>de</strong> armazenar o array em função <strong>de</strong> uma coluna ou <strong>de</strong> uma linha po<strong>de</strong> não ser<br />

eficiente em muitas situações. Consi<strong>de</strong>re-se uma representação <strong>de</strong> um array bidimensional com as<br />

dimensões Loja e Data, em que os dados relativos a Loja estão nas linhas e os valores relativos a Data<br />

nas colunas. Ace<strong>de</strong>r ao array em or<strong>de</strong>m a Lojas é eficiente, na medida em que cada página em disco<br />

contém várias Lojas. Porém, ace<strong>de</strong>r ao array em or<strong>de</strong>m a Data é ineficiente, especialmente se a<br />

dimensão Loja for gran<strong>de</strong>; nesse caso, cada página em disco só vai conter os dados relativos a uma<br />

Data, sendo necessário carregar outra página para ace<strong>de</strong>r a dados para a Data seguinte. Esta<br />

organização cria uma assimetria entre as dimensões, favorecendo uma em <strong>de</strong>trimento <strong>de</strong> outras<br />

[Zhao1997]. O recurso à estratégia <strong>de</strong> chunking faz com que o tratamento seja equitativo para todas as<br />

dimensões. Enten<strong>de</strong>-se por chunking uma forma <strong>de</strong> dividir arrays n-dimensionais em vários arrays n-<br />

dimensionais mais pequenos (chunks), que são armazenados no disco como objectos distintos<br />

[Zhao1997].<br />

Porém, especialmente no que se refere a dados reais, é frequente que muitas das células do chunk<br />

estejam vazias, o que significa que não existem dados para essa combinação <strong>de</strong> coor<strong>de</strong>nadas. Um<br />

chunk é consi<strong>de</strong>rado <strong>de</strong>nso quando mais <strong>de</strong> 40% das células contêm um valor válido [Zhao1997].<br />

Quando esta situação não se verifica, diz-se que o chunk é esparso e é necessário aplicar-lhe uma<br />

técnica <strong>de</strong> compressão <strong>de</strong> tal forma que cada célula fica associada a um valor inteiro que indica o seu<br />

afastamento (offset) em relação ao início do chunk, evitando assim o armazenamento <strong>de</strong> células vazias.<br />

Desta forma, cada entrada válida passa a ser representada por um par (afastamento, valor).O recurso ao<br />

chunking assegura a eficiência a nível <strong>de</strong> carregamento e armazenamento dos valores das células do<br />

cubo, enquanto a eficiência a nível <strong>de</strong> computação dos agregados é assegurada pelo uso da or<strong>de</strong>m<br />

correcta no seu cálculo. Para isso, o algoritmo apresenta os conceitos <strong>de</strong> or<strong>de</strong>namento óptimo das<br />

dimensões (optimal dimension or<strong>de</strong>r) e árvore <strong>de</strong> cobertura mínima <strong>de</strong> memória (minimum memory<br />

spanning tree).<br />

Apesar <strong>de</strong> ser um algoritmo característico <strong>de</strong> aplicações do tipo MOLAP, po<strong>de</strong> ser usado por sistemas do<br />

tipo ROLAP, bastando para isso percorrer a tabela que contém os dados, carregá-la para um array,<br />

computar o resultado sobre esse array e transferir os resultados obtidos para as tabelas a<strong>de</strong>quadas.<br />

Esta adaptação justifica-se pelo elevado <strong>de</strong>sempenho que este algoritmo apresenta e pela boa gestão<br />

<strong>de</strong> memória que efectua, sendo ainda mais eficiente que os algoritmos <strong>de</strong>senhados para sistemas<br />

ROLAP.<br />

2.4.3.1 Computação <strong>de</strong> agregados<br />

Para compreen<strong>de</strong>r a mecânica do algoritmo, comecemos por computar um agregado a partir <strong>de</strong> um array<br />

simples sem recorrer a chunking, assumindo que se dispõe <strong>de</strong> um array tridimensional com dimensões<br />

A, B e C. Computar o agregado AB equivale a projectar C sobre o plano AB, o que logicamente<br />

correspon<strong>de</strong> a percorrer um plano através da dimensão C e realizar a agregação até que todo o array<br />

30


tenha sido percorrido. Se o array estivesse armazenado sob a forma <strong>de</strong> vários chunks, a computação <strong>de</strong><br />

AB seria feita não percorrendo um plano completo <strong>de</strong> dimensão |A||B|, em que |A| e |B| são<br />

respectivamente o tamanho da dimensão A e B, isso seria feito chunk a chunk. Supondo que a dimensão<br />

A num chunk tem tamanho AC e que a dimensão B num chunk tem tamanho BC e que o array é orientado<br />

<strong>de</strong> tal forma que a face AB do array está <strong>de</strong> frente para o leitor, o chunk po<strong>de</strong> ter início na parte superior<br />

esquerda do array e percorrer um plano <strong>de</strong> dimensão ACBC, agregando todos os valores <strong>de</strong> C no<br />

processo. Depois <strong>de</strong> percorrido este chunk na porção superior esquerda, o varrimento <strong>de</strong>ste plano<br />

continua através do chunk imediatamente atrás do que se encontra no topo superior esquerdo e termina<br />

apenas quando o plano foi todo percorrido <strong>de</strong>ntro do array. Neste ponto, a porção do agregado AB<br />

correspon<strong>de</strong>nte ao subplano superior esquerdo <strong>de</strong> dimensão ACBC já foi computada, pelo que este plano<br />

é guardado em disco como a primeira parte do agregado AB e prosseguir com o cálculo do subplano<br />

correspon<strong>de</strong>nte a outro chunk. Desta forma, cada chunk apenas é lido uma vez e no fim <strong>de</strong> serem<br />

percorridos todos os chunks o agregado AB encontrar-se-á em disco como uma colecção <strong>de</strong> planos <strong>de</strong><br />

tamanho ACBC. A memória usada por este processo é a suficiente para conter um chunk e o plano ACBC<br />

à medida que os chunks são varridos [Zhao1997].<br />

Porém, para computar um cubo é necessário computar mais que um agregado do mesmo. Num array<br />

com as dimensões ABC, consi<strong>de</strong>re-se agora que é necessário computar AB, BC, AC, A, B, C e o<br />

agregado total. Uma abordagem ingénua consistiria em computar todos estes agregados a patir do array<br />

inicial ABC. Porém, é muito mais eficiente calcular A a partir <strong>de</strong> AB do que calcular A a partir <strong>de</strong> ABC. Se<br />

se vir a computação do cubo como uma árvore em que ABC é a raiz, AB, BC e AC <strong>de</strong>scen<strong>de</strong>m <strong>de</strong> ABC,<br />

A e C <strong>de</strong>scen<strong>de</strong>m <strong>de</strong> AC e assim sucessivamente. Como as dimensões do array e o tamanho <strong>de</strong> cada<br />

um dos chunks são conhecidos, é possível <strong>de</strong>terminar exactamente o tamanho do array correspon<strong>de</strong>nte<br />

a cada nó da árvore e estimar o espaço necessário para o seu cálculo. Isto significa que é possível<br />

<strong>de</strong>finir a árvore mínima <strong>de</strong> cobertura (minimum spanning tree) em que o pre<strong>de</strong>cessor <strong>de</strong> cada nó n é o<br />

nó n’ <strong>de</strong> menor tamanho a partir do qual n po<strong>de</strong> ser computado. O funcionamento do algoritmo apoia-se<br />

na construção da árvore mínima <strong>de</strong> cobertura para os agregados do cubo que se preten<strong>de</strong> computar.<br />

Cada agregado Di1, Di2, ..., Dik+1 é calculado a partir do pre<strong>de</strong>cessor Di1, Di2, ..., Dik+1 com tamanho<br />

mínimo; cada chunk <strong>de</strong> Di1, Di2, ..., Dik+1 é lido segundo a dimensão Dik+1 e agregado para um chunk <strong>de</strong><br />

Di1, Di2, ..., Dik. Quando o chunk <strong>de</strong> Di1, Di2, ..., Dik estiver completo, é guardado em disco e a memória é<br />

libertada para o chunk seguinte <strong>de</strong> Di1, Di2, ..., Dik [Zhao1997].<br />

O recurso ao chunking assegura a eficiência a nível <strong>de</strong> carregamento e armazenamento dos valores das<br />

células do cubo, enquanto a eficiência a nível <strong>de</strong> <strong>de</strong>sempenho é assegurada pelo uso da or<strong>de</strong>m correcta<br />

no cálculo dos agregados. A or<strong>de</strong>m das dimensões num chunk po<strong>de</strong> ser representada como O = (Dj1, Dj2,<br />

... , Djn), assumindo que existem n dimensões D1, D2, ..., Dn. Diferentes or<strong>de</strong>namentos <strong>de</strong> dimensões<br />

implicam diferentes or<strong>de</strong>ns <strong>de</strong> leitura dos chunks e <strong>de</strong>terminam a quantida<strong>de</strong> <strong>de</strong> memória que é<br />

necessária para efectuar a computação. Para mostrar a importância da or<strong>de</strong>m pela qual são tomadas as<br />

dimensões, consi<strong>de</strong>re-se um array <strong>de</strong> dados 3D com três dimensões (A, B e C), dividido em 64 chunks<br />

31


como mostra a figura 9. Assume-se que a cardinalida<strong>de</strong> <strong>de</strong> cada uma das dimensões A, B e C é,<br />

respectivamente, 40, 400 e 4000.<br />

Figura 14 - Array 3D para as dimensões A, B e C, dividido em 64 chunks<br />

Os chunks são lidos segundo a or<strong>de</strong>m ABC, do chunk 1 para o chunk 64. Assumindo que o chunk 1 já<br />

está carregado em memória, este é agregado segundo a dimensão C para obter um chunk <strong>de</strong> AB,<br />

segundo a dimensão i para obter um chunk <strong>de</strong> AC e segundo a dimensão A para obter um chunk <strong>de</strong> BC.<br />

Assim, o primeiro chunk <strong>de</strong> AB é agregado para o chunk a0b0 <strong>de</strong> AB, o primeiro chunk <strong>de</strong> AC é agregado<br />

para o chunk a0c0 <strong>de</strong> AC e o primeiro chunk <strong>de</strong> BC é agregado para o chunk b0c0 <strong>de</strong> BC. À medida que<br />

novos chunks são lidos, os chunks obtidos vão sendo agrupados aos chunks dos agregados<br />

correspon<strong>de</strong>ntes. Note-se que os chunks foram lidos segundo a or<strong>de</strong>m (A, B, C), que correspon<strong>de</strong> a uma<br />

or<strong>de</strong>m linear <strong>de</strong>s<strong>de</strong> o chunk 1 ao chunk 64. Isso significa que b0c0 está completamente agregado <strong>de</strong>pois<br />

<strong>de</strong> terem sido lidos os chunks 1 a 4, após o que é guardado em disco e a sua memória é atribuida ao<br />

chunk b1c0. Este, por sua vez, está completamente agregado <strong>de</strong>pois <strong>de</strong> terem sido lidos os chunks 5 a 8,<br />

e assim sucessivamente. Isto significa que apenas um chunk <strong>de</strong> BC se encontra em memória durante o<br />

cálculo do agregado BC. Da mesma forma, é reservada memória para os chunks a0c0, a1c0, a2c0 e a3c0<br />

enquanto são percorridos os primeiros 16 chunks <strong>de</strong> ABC. Para terminar a agregação para o chunk a0c0,<br />

o resultado da agregação dos chunks 1, 5, 9 e 13 são acumulados no chunk a0c0, esses chunks <strong>de</strong> AC<br />

são escritos para disco e a sua memória atribuída a a0c1, a1c1, a2c1 e a3c1 do agregado AC. Por fim, para<br />

calcular o agregado AB é necessário alocar memória para um total <strong>de</strong> 64 chunks. Neste exemplo, para<br />

calcular BC é necessário memória para 1 chunk <strong>de</strong> BC, para calcular AC é necessária memória para 4<br />

chunks <strong>de</strong> AC e para calcular BC é necessário memória para 4 x 4 = 16 chunks <strong>de</strong> AB [Zhao1997].<br />

Genericamente, é necessário alocar |Bc||Cc|u memória para calcular um agregado BC, |Ad||Cc|u para<br />

calcular um agregado AC e |Ad||Bd|u para calcular um agregado AB, em que |Xd| representa o tamanho<br />

<strong>de</strong> uma dimensão X, |Xc| o tamanho do chunk <strong>de</strong> uma dimensão X e u o tamanho <strong>de</strong> cada elemento do<br />

chunk [Zhao1997]. Como o tamanho <strong>de</strong> um chunk <strong>de</strong> uma dimensão é menor que o tamanho <strong>de</strong>ssa<br />

dimensão na maioria dos casos, conclui-se que é possível calcular o cubo alocando uma quantida<strong>de</strong> <strong>de</strong><br />

32


Diferentes or<strong>de</strong>nações <strong>de</strong> dimensões (D1, D2, ..., Dn) po<strong>de</strong>m gerar diferentes MMSTs com diferentes<br />

requisitos a nível <strong>de</strong> memória. Para exemplificar isto, consi<strong>de</strong>re-se um array com quatro dimensões<br />

ABCD com 10 x 10 x 10 x 10 chunks, em que |A| = 10, |B| = 100, |C| = 1000 e |D| = 10000. A figura<br />

seguinte mostra as MMSTs geradas para a or<strong>de</strong>nação <strong>de</strong> dimensões (A, B, C, D) e (D, B, C, A),<br />

respectivamente. Verifica-se que a MMST para a or<strong>de</strong>nação (D, B, C, A) requer aproximadamente 4 Gb<br />

<strong>de</strong> memória, enquanto a MMST para a or<strong>de</strong>nação (A, B, C, D) requer apenas 4 Mb <strong>de</strong> memória. A<br />

disparida<strong>de</strong> entre os requisitos <strong>de</strong> memória <strong>de</strong>ve-se unicamente ao facto da troca entre A e D na<br />

sequência das dimensões.<br />

Figura 16 - Requisitos <strong>de</strong> memória para duas or<strong>de</strong>nações diferentes das dimensões [Zhao1997]<br />

Se a quantida<strong>de</strong> <strong>de</strong> memória disponível for inferior à memória mínima indicada como necessária pela<br />

MMST, isso significa que não será possível reservar memória para algumas sub-árvores da MMST. Por<br />

forma a contornar esta situação, os autores propõem que a MMST seja dividida na sub-árvore<br />

operacional, para a qual existe espaço suficiente em memória, e num conjunto <strong>de</strong> sub-árvores<br />

incompletas, ou seja, aquelas para as quais não existe espaço suficiente em memória. Para <strong>de</strong>cidir por<br />

que or<strong>de</strong>m <strong>de</strong>ve ser atribuída memória a cada uma das sub-árvores, os autores propõem que se utilize<br />

uma heurística segundo a qual a memória começa a ser atribuída a partir da raiz e da direita para<br />

esquerda, por forma a evitar uma computação em múltiplos passos do array <strong>de</strong> maior dimensão.<br />

2.4.3.2 Variante do algoritmo Multi-Way no sistema DBMiner<br />

Devido ao seu bom <strong>de</strong>sempenho, este algoritmo foi integrado no sistema DBMiner [Tam1998]. A i<strong>de</strong>ia<br />

subjacente a este sistema resulta <strong>de</strong> observações na área da pesquisa em bases <strong>de</strong> dados, que<br />

mostram que normalmente as tarefas <strong>de</strong> exploração <strong>de</strong> dados são realizadas sobre extensos conjuntos<br />

34


<strong>de</strong> dados, frequentemente mantidos para outros fins, e que na maioria dos casos os utilizadores não<br />

conseguem estabelecer um objectivo <strong>de</strong>finido. Isto leva a que as interrogações colocadas impliquem a<br />

agregação <strong>de</strong> gran<strong>de</strong>s quantida<strong>de</strong>s <strong>de</strong> dados, o que impossibilita a rapi<strong>de</strong>z <strong>de</strong>sejada na resposta. O<br />

objectivo do sistema proposto seria, portanto, conseguir que as ferramentas <strong>de</strong> data mining<br />

trabalhassem em conjunto com as ferramentas <strong>de</strong> OLAP <strong>de</strong> uma data warehouse por forma a aumentar<br />

a qualida<strong>de</strong> e rentabilida<strong>de</strong> da experiência para o utilizador, numa perspectiva a que foi dado o nome <strong>de</strong><br />

OLAP mining. Um dos principais <strong>de</strong>safios na criação <strong>de</strong> um sistema <strong>de</strong>stes é a necessida<strong>de</strong> <strong>de</strong> uma<br />

implementação eficiente do mecanismo <strong>de</strong> computação e construção do cubo, que permita uma<br />

capacida<strong>de</strong> <strong>de</strong> resposta rápida. Com base no operador CUBE [Gray1997] e no algoritmo Multi-Way<br />

[Zhao1997], Tam propôs um algoritmo <strong>de</strong> computação <strong>de</strong> agregados cujas principais características são<br />

o facto <strong>de</strong> percorrer a relação uma única vez, computar um agregado a partir do menor agregado já<br />

computado, computar simultaneamente o maior número <strong>de</strong> agregados possível e retirar os agregados <strong>de</strong><br />

memória o mais cedo possível <strong>de</strong> forma a libertar memória para a computação <strong>de</strong> outros agregados<br />

[Tam1998]. Em traços gerais, o algoritmo proposto baseia-se no conceito <strong>de</strong> um cubo baseado em<br />

chunks, em que o cubo é armazenado sob a forma uma tabela relacional e os seus chunks armazenados<br />

como tuplos. Para cada chunk, as células são mapeadas para um en<strong>de</strong>reço <strong>de</strong> memória que po<strong>de</strong> ser<br />

guardado como um dos campos do tuplo, <strong>de</strong> forma a que não seja necessário utilizar mecanismos <strong>de</strong><br />

in<strong>de</strong>xação para ace<strong>de</strong>r aos chunks. No fundo, são combinadas características <strong>de</strong> sistemas ROLAP e<br />

MOLAP num único algoritmo.<br />

No trabalho realizado por Tam, o conceito <strong>de</strong> cubo foi <strong>de</strong>senhado tendo em conta um contexto dirigido<br />

por interrogações (query-driven), no qual o número <strong>de</strong> dimensões do cubo não é conhecido enquanto a<br />

interrogação não é submetida. Por essa razão, conceptualmente o cubo é multidimensional mas é<br />

implementado como um array unidimensional. Sendo D0, D1, ..., DN-1 as dimensões <strong>de</strong> um cubo N-<br />

dimensional, é adicionado o valor ALL a cada dimensão Di, tal como <strong>de</strong>scrito por [Gray1997], o que faz<br />

com que qualquer célula em que o valor ALL faça parte do seu en<strong>de</strong>reço corresponda a um agregado.<br />

Este tipo <strong>de</strong> células é <strong>de</strong>signado como célula cubói<strong>de</strong> (cuboid cell), enquanto as restantes células são<br />

consi<strong>de</strong>radas células nucleares (core cells). Os valores <strong>de</strong> cada dimensão são mapeados para<br />

coor<strong>de</strong>nadas <strong>de</strong> tal forma que a dimensão Di corresponda aos valores {di0, di1, ..., di|Di|-1, diALL}. A posição<br />

<strong>de</strong> cada célula do cubo é <strong>de</strong>notada no espaço multidimensional pelo vector V(v0, v1, ..., vN-1), sendo a<br />

magnitu<strong>de</strong> <strong>de</strong> cada vector equivalente ao número <strong>de</strong> dimensões do cubo. Portanto, para uma célula<br />

cubói<strong>de</strong>, o seu en<strong>de</strong>reço contém pelo menos um componente vj tal que vj = |Dj|, j ≥ 0 e j < N. Assim, a<br />

célula cujo en<strong>de</strong>reço é dado pelo vector V(|D0|, ..., |DN-1|) trata-se da célula cubói<strong>de</strong> correspon<strong>de</strong>nte ao<br />

agregado vazio ALL [Tam1998]. Tomando o cubo C tridimensional na figura 12, verifica-se que existem<br />

três dimensões, em que |D0| = 5, |D1| = 4, |D2| = 3, e que os valores para cada dimensão são di0 = 0, di1 =<br />

1 e assim sucessivamente para i = 0,1, 2. A célula cubói<strong>de</strong> com o en<strong>de</strong>reço V(5, 4, 3) correspon<strong>de</strong>,<br />

então, à célula (ALL, ALL, ALL). Seguindo ainda esta notação, a célula com o en<strong>de</strong>reço V(5, 0, 0) guarda<br />

o resultado da soma das medidas das células {V(0, 0, 0), V(1, 0, 0), V(2, 0, 0), V(3, 0, 0), V(4, 0, 0)},<br />

35


enquanto a célula com o en<strong>de</strong>reço V(5, 4, 0) guarda o resultado da soma das medidas das células S1 =<br />

{V(5, 0, 0), V(5, 1, 0), V(5, 2, 0), V(5, 3, 0)} ou das células S2 = {V(0, 4, 0), V(1, 4, 0), V(2, 4, 0), V(3, 4,<br />

0), V(4, 4, 0)}. Desta forma, a célula V(5, 4, 0) <strong>de</strong>pen<strong>de</strong> <strong>de</strong> dois conjuntos <strong>de</strong> células diferentes, ou seja,<br />

S1 e S2 são sub-cubói<strong>de</strong>s potenciais do cubói<strong>de</strong> V(5, 4, 0)<br />

Figura 17 <strong>–</strong> Representação <strong>de</strong> um cubo 3D segundo [Tam1998]<br />

O facto do cubo ser implementado como um array unidimensional significa que as células do cubo C são<br />

or<strong>de</strong>nadas como mostra a tabela <strong>de</strong> tal forma que o en<strong>de</strong>reço V(0, 0, 0) e V(0, 1, 0) estão nas posições 0<br />

e 4, respectivamente, do array; a última célula do cubo C (V(5, 4, 3)) está guardada na posição 119 uma<br />

vez que existem (5 + 1) x (4 + 1) x (3 + 1) = 120 células no total. O mapeamento entre o espaço<br />

multidimensional e o espaço unidimensional é realizado pelos algoritmos Vector-To-In<strong>de</strong>x e In<strong>de</strong>x-To-<br />

Vector [Tam1998].<br />

Tabela 8 <strong>–</strong> Or<strong>de</strong>m das células do cubo no array [Tam1998]<br />

V(0, 0, 0) V(0, 0, 1) ... V(0, 0, |D 2|)<br />

V(0, 1, 0) V(0, 1, 1) ... V(0, 1, |D 2|)<br />

... ... ... ...<br />

V(0, |D 1|, 0) V(0, |D 1|, 1) ... V(0, |D 1|, |D 2|)<br />

V(1, 0, 0) V(1, 0, 1) ... V(1, 0, |D 2|)<br />

... ... ... ...<br />

V(|D 0|, 2, 0) V(|D 0|, 2, 1) ... V(|D 0|, 2, |D 2|)<br />

... ... ... ...<br />

V(|D 0|, |D 1|, 0) V(|D 0|, |D 1|, 1) ... V(|D 0|, |D 1|, |D 2|)<br />

36


Com base no algoritmo <strong>de</strong> Zhao et al, o array é dividido em chunks, cada um dos quais <strong>de</strong>ve ter uma<br />

dimensão que lhe permita existir em memória. No seguimento da notação utilizada, um chunk po<strong>de</strong> ser<br />

um chunk nuclear (core chunk) ou um chunk cubói<strong>de</strong> (cuboid chunk). A maioria dos chunks cubói<strong>de</strong>s são<br />

pequenos e acedidos mais frequentemente, pelo que <strong>de</strong>vem ser separados dos chunks nucleares para<br />

assegurar um acesso rápido aos primeiros. Porém, como nem todos os chunks <strong>de</strong> um cubo têm o<br />

mesmo volume, é necessário <strong>de</strong>terminar qual o tamanho dos chunks. Para esse fim, é estabelecido um<br />

limite e verifica-se se o tamanho da maior dimensão po<strong>de</strong> ser usado como limite para todas as<br />

dimensões. Tomando o exemplo do cubo 3D da figura 12 e assumindo um limite máximo <strong>de</strong> 27 células,<br />

ao seleccionar o valor <strong>de</strong> |D0| = 5 verifica-se que um chunk teria 5 x 4 x 3 = 60 células, o que ultrapassa o<br />

limite pré-estabelecido. A estratégia passa por dividir o valor <strong>de</strong> |D0| por 2 e adicionar 1 ao resultado<br />

obtido, enquanto o valor obtido não respeitar o limite estabelecido [Tam1998]. A figura abaixo mostra o<br />

cubo C após ter sofrido chunking.<br />

Figura 18 <strong>–</strong> Representação do cubo C com 18 chunks [Tam1998]<br />

Cada chunk é tratado como um cubo, o que significa que conceptualmente existem dois mo<strong>de</strong>los<br />

multidimensionais: o mo<strong>de</strong>lo global, que <strong>de</strong>termina os i<strong>de</strong>ntificadores dos chunks, e o mo<strong>de</strong>lo local, que<br />

<strong>de</strong>termina os afastamentos (offsets) das células <strong>de</strong>ntro <strong>de</strong> cada chunk. Logo, cada célula do cubo está<br />

sempre associada a um vector global e um vector local, que po<strong>de</strong>m ser obtidos a partir do en<strong>de</strong>reço da<br />

célula. Tendo em conta a divisão do cubo em chunks, a última célula cubói<strong>de</strong> do cubo C encontra-se em<br />

V(5, 4, 3) e é agora a única célula do chunk 17. Para obter o vector global GV = (gv0, gv1, gv2) para esta<br />

célula, começa-se em v0 e compara-se esse valor com o tamanho do primeiro segmento da dimensão<br />

D0, que é 2 neste caso. Como 5 ≥ 3, toma-se o tamanho do segmento seguinte, que é 2, e como<br />

5 ≥ 3 + 2, termina-se no último segmento e conclui-se que gv0 = 2. Da mesma forma, para as dimensões<br />

37


Figura 20 <strong>–</strong> MNST para o cubo C [Tam1998]<br />

Qualquer nó M num nível i abaixo do nível 0 po<strong>de</strong> ser computado a partir dos nós no nível acima cujas<br />

dimensões contenham todas as dimensões que compõem esse nó. Isto significa que po<strong>de</strong> existir mais<br />

do que um nó a partir no nível i-1 a partir do qual o nó M po<strong>de</strong> ser computado. A razão da existência<br />

<strong>de</strong>sta estrutura pren<strong>de</strong>-se com o facto <strong>de</strong>, em vez <strong>de</strong> seleccionar o nó no nível i-1 que permita calcular o<br />

nó M com menor requisito <strong>de</strong> memória possível, o algoritmo implementado por Tam seleccionar o nó que<br />

requer o menor número possível <strong>de</strong> células cubói<strong>de</strong>s para se conseguir computar o nó M. Segundo esta<br />

lógica e tendo em conta a MNST na figura 15, para computar o agregado ALL seria escolhido o nó 2 e<br />

não o nó 1 uma vez que o nó 2 requer |D2| células e o nó requer |D1| células para computar esse<br />

agregado e |D2| < |D1|. Como razões para o uso <strong>de</strong>sta estrutura em <strong>de</strong>trimento da MMST, são indicadas<br />

a maior facilida<strong>de</strong> na sua construção <strong>de</strong>vido ao facto <strong>de</strong> não ser necessário realizar cálculos <strong>de</strong><br />

requisitos <strong>de</strong> memória, o facto <strong>de</strong> serem estruturas equivalente em termos <strong>de</strong> necessida<strong>de</strong>s <strong>de</strong> memória<br />

e da MNST permitir usar um menor número <strong>de</strong> subcubói<strong>de</strong>s para computar um agregado.<br />

Com base nestes conceitos, Tam propõe um algoritmo <strong>de</strong>signado como R-cubing, cujo funcionamento é<br />

explicado <strong>de</strong> seguida com base na MNST na figura 15. Como a célula em V(0, 0, 0) é uma célula<br />

nuclear, a MNST é percorrida a partir do nó 012 no nível 0. Sabendo que o nó 012 po<strong>de</strong> ser computado a<br />

partir dos nós 01, 02 e 12 segundo as dimensões D2, D1 e D0, respectivamente, a célula V(0, 0, 0) é<br />

adicionada às células cubói<strong>de</strong>s em V(0, 0, 3) segundo a dimensão D2, V(0, 4, 0) segundo a dimensão D1<br />

e V(5, 0, 0) segundo D0. No total, estão três células cubói<strong>de</strong>s em memória. O processo repete-se para a<br />

célula nuclear seguinte em V(0, 0, 1), que é adicionado a V(0, 0, 3), V(0, 4, 1) e V(5, 0 ,1), o que faz com<br />

que mais duas células cubói<strong>de</strong>s sejam carregadas para memória. Da mesma forma, a célula nuclear em<br />

V(0, 0, 2) é adicionada a V(0, 0, 3), V(0, 4, 2) e V(5, 0, 2), forçando o carregamento <strong>de</strong> mais duas células<br />

cubói<strong>de</strong>s para memória. Neste ponto, a célula cubói<strong>de</strong> em V(0, 0, 3) contém todas as somas<br />

39


necessárias, pelo que é necessário verificar na MNST se esta célula é útil para o cálculo <strong>de</strong> outras. Na<br />

MNST, este agregado corrrespon<strong>de</strong> ao nó 01 e não possui quaisquer nós <strong>de</strong>pen<strong>de</strong>ntes <strong>de</strong> si; logo, V(0,<br />

0, 3) é guardado em disco e a memória associada libertada. As células nucleares em V(0, 1, 0), V(0, 1,<br />

1), V(0, 1, 2), V(0, 2, 0), ..., V(0, 3, 1), V(0, 3, 2) são <strong>de</strong>pois examinadas e adicionadas às<br />

correspon<strong>de</strong>ntes células cubói<strong>de</strong>s. Novamente, as células cubói<strong>de</strong>s em V(0, 1, 3), V(0, 2, 3) e V(0, 3, 3)<br />

estão completas e po<strong>de</strong>m ser guardadas em disco. Note-se que, aquando da leitura da célula nuclear<br />

V(0, 3, 0), o valor que contém vai ser adicionado à célula cubói<strong>de</strong> em V(0, 4, 0), o que faz com que esta<br />

célula esteja completa. Segundo a MNST, esta célula cubói<strong>de</strong> refere-se ao nó 02 e <strong>de</strong>le <strong>de</strong>pen<strong>de</strong>m o nó<br />

0 no nível 2. Logo, a célula V(0, 4, 0) é adicionada à célula V(0, 4, 3) segundo a dimensão D2. Este<br />

processo, tal como ilustrado na figura 16, é repetido para cada célula nuclear e cubói<strong>de</strong> até que todas as<br />

células nucleares tenham sido percorridas e todas as células cubói<strong>de</strong>s tenham sido materializadas<br />

[Tam1998]. Como se pô<strong>de</strong> verificar, antes <strong>de</strong> uma célula cubói<strong>de</strong> ser guardada e a memória associada<br />

libertada tem que cumprir dois requisitos: essa célula <strong>de</strong>ve ter sido completamente materializada, ou<br />

seja, <strong>de</strong>ve conter o resultado da soma <strong>de</strong> todas as células subcubói<strong>de</strong>s correspon<strong>de</strong>ntes e já <strong>de</strong>ve ter<br />

sido adicionada a todos os cubói<strong>de</strong>s que <strong>de</strong>la <strong>de</strong>pen<strong>de</strong>m.<br />

Figura 21 <strong>–</strong> Relação entre cubói<strong>de</strong>s e subcubói<strong>de</strong>s em relação à célula V(0, 0, 0) usando R-cubing [Tam1998]<br />

Porém, tal como referido anteriormente, o conceito <strong>de</strong> cubo implementado por Tam é o <strong>de</strong> um cubo<br />

baseado em chunks, pelo que em vez <strong>de</strong> uma célula ser adicionada a outra na realida<strong>de</strong> um chunk<br />

subcubói<strong>de</strong> é adicionado a outro chunk subcubói<strong>de</strong>. Segundo o algoritmo proposto, o chunk 0 é<br />

40


adicionado ao chunk 12 segundo D0, ao chunk 4 segundo D1 e ao chunk 1 segundo D2, tal como mostra<br />

a figura 17. No fundo, o processo <strong>de</strong> somar um chunk subcubói<strong>de</strong> a outro equivale a comprimir esse<br />

subcubói<strong>de</strong> segundo uma dimensão Da <strong>de</strong> tal forma que o vector local da célula subcubói<strong>de</strong> do chunk<br />

passa a ter lva = 0 [Tam1998]. Na situação da figura 17, as células {0, 9, 18} do chunk 0 (LV(0, 0, 0),<br />

LV(1, 0, 0) e LV(2, 0, 0)) são adicionadas à célula 0 do chunk 12 (LV(0, 0, 0)) segundo a dimensão D0; as<br />

células {0, 3, 6} do chunk 0 (LV(0, 0, 0), LV(0, 1, 0) e LV(0, 2, 0)) são adicionadas à célula 0 do chunk 4<br />

segundo a dimensão D1; as células {15, 16, 17} do chunk 0 (LV(1, 2, 0), LV(1, 2, 1) e LV(1, 2, 2)) são<br />

adicionadas à célula 5 do chunk 1 (LV(1, 2, 0)) segundo a dimensão D2.<br />

Figura 22 <strong>–</strong> Processo <strong>de</strong> adição do chunk 0 aos chunks subcubói<strong>de</strong>s relacionados [Tam1998]<br />

Conclui-se, assim, que Tam não implementou o algoritmo Multi-Way tal como proposto por Zhao et al<br />

[Zhao1997], mas antes que se baseou em conceitos básicos, como o chunking, o or<strong>de</strong>namento óptimo<br />

das dimensões e a MMST para <strong>de</strong>senvolver e implementar um algoritmo que combina características<br />

tanto da abordagem ROLAP como da abordagem MOLAP. Apesar <strong>de</strong> provavelmente ter realizado<br />

previamente um estudo sobre o algoritmo Multi-Way como forma <strong>de</strong> analisar os seus pontos fortes e<br />

fracos, não existem quaisquer dados sobre esse estudo ou a implementação usada para tal. No final do<br />

seu trabalho, é feita uma comparação entre o algoritmo implementado e o algoritmo Multi-Way apenas<br />

em termos do tempo <strong>de</strong> execução, que mostra que ambos os algoritmos têm um <strong>de</strong>sempenho<br />

semelhante para conjuntos <strong>de</strong> dados com baixo número <strong>de</strong> dimensões e que o <strong>de</strong>sempenho do<br />

41


algoritmo Multi-Way se <strong>de</strong>teriora quando aumenta o número <strong>de</strong> dimensões em consequência do elevado<br />

custo associado à construção da MMST [Tam1998].<br />

2.5 Variantes ao problema tradicional<br />

Os trabalhos mais recentes na área <strong>de</strong> OLAP e geração <strong>de</strong> hipercubos inci<strong>de</strong>m sobre uma variante do<br />

problema tradicional da computação <strong>de</strong> cubos. Como se viu, o problema tradicional consiste, muito<br />

resumidamente, em calcular todos os agregados da forma mais eficiente possível, tendo em conta que o<br />

problema é exponencial em relação ao número <strong>de</strong> dimensões consi<strong>de</strong>radas. Além disso, há que ter em<br />

atenção que o tamanho <strong>de</strong> cada agregado <strong>de</strong>pen<strong>de</strong> da cardinalida<strong>de</strong> das dimensões que o compõem.<br />

Como os dados reais ten<strong>de</strong>m a ser <strong>de</strong> natureza esparsa, uma estratégia para aumentar o <strong>de</strong>sempenho<br />

dos algoritmos nessas situações passa por i<strong>de</strong>ntificar antes da computação quais os subconjuntos <strong>de</strong><br />

interesse [Beyer1999] apresentaram uma variante ao problema tradicional da geração <strong>de</strong> cubos a que<br />

<strong>de</strong>ram o nome <strong>de</strong> cubos iceberg (iceberg cubes). O problema icerberg-CUBE consiste em computar<br />

todas as agregações para todas as combinações <strong>de</strong> atributos que satisfazem uma <strong>de</strong>terminada<br />

condição, à semelhança da cláusula HAVING numa interrogação SQL. Tendo em conta o contexto <strong>de</strong><br />

dados esparsos, a condição envolvida estabelece que uma partição <strong>de</strong>ve ter pelo menos N tuplos, sendo<br />

N <strong>de</strong>signado como o suporte mínimo da partição.<br />

2.5.1 Computação da base para o topo (bottom-up computation)<br />

Beyer e Ramakrishnan propuseram o algoritmo BUC como resposta ao problema dos cubos iceberg.<br />

Este algoritmo procura combinar a eficiência a nível <strong>de</strong> entradas/saídas do algoritmo Partitioned-Cube<br />

com a possibilida<strong>de</strong> <strong>de</strong> recorrer a filtragem em função do suporte mínimo pretendido [Beyer1999]. A sua<br />

<strong>de</strong>signação <strong>de</strong>ve-se ao facto do algoritmo começar nos agregados mais pequenos e prosseguir até aos<br />

agregados maiores, ao contrário da maioria dos restantes algoritmos. Cada dimensão é lida e dividida<br />

segundo o número <strong>de</strong> ocorrências para cada um dos valores <strong>de</strong>ssa dimensão, sendo as restantes<br />

dimensões computadas recursivamente para cada partição.<br />

O algoritmo recorre à estratégia dividir para conquistar (divi<strong>de</strong>-and-conquer) uma vez que, após uma<br />

<strong>de</strong>terminada partição ter sido calculada, todos os cubói<strong>de</strong>s <strong>de</strong>scen<strong>de</strong>ntes são calculados antes do<br />

algoritmo passar à partição seguinte. O movimento da base para o topo, ou seja, no sentido dos<br />

agregados mais pequenos para os agregados maiores, permite que seja realizada uma filtragem<br />

recorrendo à proprieda<strong>de</strong> anti-monotónica empregue no algoritmo Apriori, usado na <strong>de</strong>scoberta <strong>de</strong><br />

associações frequentes entre objectos [Agrawal1994] que estabelece que, se a contagem numa célula c<br />

<strong>de</strong> um cubói<strong>de</strong> A é inferior a um limite mínimo estabelecido, então o valor para qualquer uma das células<br />

que partilhem com essa célula um prefixo comum nunca será superior ao limite pré-estabelecido; logo,<br />

essas células <strong>de</strong>scen<strong>de</strong>ntes não precisam <strong>de</strong> ser calculadas.<br />

42


Os resultados mostram que o algoritmo BUC apresenta melhor <strong>de</strong>sempenho na computação <strong>de</strong> cubos<br />

esparsos do que o algoritmo Memory-Cube [Beyer1999].<br />

2.5.2 H-cubing<br />

Han et al [Han2001]propuseram um algoritmo orientado para a resolução do problema dos cubos iceberg<br />

mas para a situação específica em que a condição a ser satisfeita pelos agregados envolve uma medida<br />

não distributiva, como a média. O recurso a este tipo <strong>de</strong> medidas, que normalmente não obe<strong>de</strong>cem à<br />

proprieda<strong>de</strong> anti-monotónica, faz com que não possa ser feito filtragem com base nessa proprieda<strong>de</strong>. No<br />

caso concreto da média, o facto <strong>de</strong> o valor médio numa célula c <strong>de</strong> um cubói<strong>de</strong> A ser inferior a um valor<br />

mínimo pré-<strong>de</strong>finido não significa obrigatoriamente que o valor das células <strong>de</strong>scen<strong>de</strong>ntes seja igualmente<br />

inferior.<br />

O algoritmo proposto utiliza uma estrutura em árvore (H-tree) baseada na FP-tree usada pelo algoritmo<br />

FP-growth [Han1999]. São características <strong>de</strong>sta estrutura o facto <strong>de</strong> po<strong>de</strong>r ser construída com um único<br />

varrimento da base <strong>de</strong> dados e a sua completu<strong>de</strong>, no sentido em que a H-tree e respectiva tabela<br />

(hea<strong>de</strong>r table) fornecem toda a informação necessária para calcular um cubo iceberg. Cada nível da<br />

árvore representa uma dimensão no cubói<strong>de</strong> base e cada tuplo <strong>de</strong> d-dimensões compõe um caminho<br />

com d nós na árvore. Os nós que se encontram ao mesmo nível e contêm o mesmo valor estão ligados<br />

entre si. A cada nível está associada uma tabela (hea<strong>de</strong>r table) que regista a frequência <strong>de</strong> cada um dos<br />

valores possíveis das dimensões e mantém ligações aos primeiros nós correspon<strong>de</strong>ntes a esses valores.<br />

Figura 23 - Exemplo <strong>de</strong> uma H-tree [Agrawal1994]<br />

43


A partir <strong>de</strong>sta estrutura, o cubo po<strong>de</strong> ser calculado da base para o topo (bottom-up) ou do topo para a<br />

base (top-down). Em qualquer das estratégias, o algoritmo começa num <strong>de</strong>terminado nível da árvore e<br />

analisa todos os agregados que incluem a dimensão correspon<strong>de</strong>nte a esse nível e as dimensões<br />

correspon<strong>de</strong>ntes aos níveis superiores. A agregação é facilitada pela tabela (hea<strong>de</strong>r table): se o valor<br />

para um <strong>de</strong>terminado nó é inferior ao mínimo estabelecido, a agregação ―salta‖ para o próximo nó<br />

através do ponteiro lateral. A diferença entre as duas estratégias é o ponto <strong>de</strong> entrada do algoritmo, que<br />

é na base da árvore no caso da direcção ascen<strong>de</strong>nte (bottom-up) e no topo da árvore no caso da<br />

direcção <strong>de</strong>scen<strong>de</strong>nte (top-down).<br />

Uma das vantagens <strong>de</strong>ste algoritmo resi<strong>de</strong> exactamente na estrutura da H-tree que, ao eliminar a<br />

duplicação <strong>de</strong> dados, permite que se tire partido da computação simultânea <strong>de</strong> agregados e que sejam<br />

calculadas menos combinações <strong>de</strong> dimensões.<br />

2.5.3 Star-Cubing<br />

Xin et al propuseram um algoritmo que procura combinar os pontos fortes dos algoritmo Multi-Way, BUC<br />

e H-Cubing. Basicamente, o algoritmo Star-Cubing integra as potencialida<strong>de</strong>s da computação da base<br />

para o topo (bottom-up) e do topo para a base (top-down) com algumas técnicas <strong>de</strong> optimização do<br />

<strong>de</strong>sempenho. No que se refere à or<strong>de</strong>m <strong>de</strong> computação global, utiliza um mo<strong>de</strong>lo do topo para a base<br />

(top-down) e este é complementado por uma abordagem da base para o topo (bottom-up) implementada<br />

por uma camada inferior do algoritmo. Esta integração permite que o algoritmo consiga efectuar<br />

agregações sobre várias dimensões sem per<strong>de</strong>r a capacida<strong>de</strong> <strong>de</strong> dividir os agregados pais e realizar<br />

filtragem sobre os agregados filhos que não respeitam a condição iceberg [Xin2003].<br />

Uma das optimizações introduzidas passa pelo conceito <strong>de</strong> dimensões partilhadas, que facilita a<br />

agregação partilhada. Observando a figura 24, verifica-se que todos os nós da árvore mais à esquerda<br />

incluem as dimensões ABC, todos os nós na segunda sub-árvore incluem as dimensões AB e todos os<br />

nós na terceira sub-árvore incluem a dimensão A. A estas dimensões comuns em várias sub-árvores dá-<br />

se o nome <strong>de</strong> dimensões partilhadas.<br />

Figura 24 - Árvore <strong>de</strong> computação top-down [Xin2003]<br />

44


Como as dimensões partilhadas po<strong>de</strong>m ser i<strong>de</strong>ntificadas numa fase inicial, isso significa que po<strong>de</strong> ser<br />

avaliada a necessida<strong>de</strong> <strong>de</strong> computar <strong>de</strong>terminados agregados posteriormente. Se a condição iceberg for<br />

anti-monotónica e o valor agregado numa dimensão partilhada não satisfizer essa condição, todos os<br />

agregados que esten<strong>de</strong>m essa dimensão partilhada não satisfazem igualmente a condição e, como tal,<br />

não precisam <strong>de</strong> ser computados. Esta capacida<strong>de</strong> <strong>de</strong> conseguir <strong>de</strong>terminar o mais cedo possível<br />

durante a computação que <strong>de</strong>terminados agregados não necessitam <strong>de</strong> ser calculados é outra das<br />

optimizações importantes integradas no algoritmo. Outra optimização relevante é o uso <strong>de</strong> uma estrutura<br />

semelhante à H-tree mas com maior capacida<strong>de</strong> <strong>de</strong> compressão (star-tree).<br />

Os resultados a nível <strong>de</strong> <strong>de</strong>sempenho para este algoritmo foram semelhantes aos conseguidos pelo<br />

algoritmo Multi-Way para cubos completos e melhores que os obtidos pelos vários algoritmos para cubos<br />

esparsos, em gran<strong>de</strong> parte <strong>de</strong>vido ao facto do algoritmo conseguir integrar várias optimizações.<br />

45


3 Trabalho realizado<br />

Esta secção <strong>de</strong>screve os principais aspectos da implementação realizada e as alterações propostas ao<br />

algoritmo Multi-Way no sentido <strong>de</strong> aumentar a capacida<strong>de</strong> <strong>de</strong> gestão <strong>de</strong> memória do mesmo e,<br />

consequentemente, o número <strong>de</strong> situações em que po<strong>de</strong> ser aplicado.<br />

3.1 Motivação<br />

O estudo dos trabalhos realizados nesta área mostra que a computação <strong>de</strong> agregados multidimensionais<br />

e agregados é uma operação fundamental no que se refere às aplicações OLAP, tendo sido concebidos<br />

diferentes algoritmos e estratégias <strong>de</strong> optimização para esse fim. Porém, muitos dos algoritmos<br />

anteriormente apresentados foram <strong>de</strong>senvolvidos para sistemas ROLAP, sendo o número <strong>de</strong> algoritmos<br />

<strong>de</strong>senhados para sistemas MOLAP bastante inferior. Os sistemas do tipo MOLAP são mais afectados<br />

pelo carácter esparso dos dados, uma situação frequente na vida real, mas conseguem alcançar uma<br />

eficiência semelhante à dos algoritmos para sistemas ROLAP <strong>de</strong>s<strong>de</strong> que sejam aplicadas técnicas que<br />

lhes permitam lidar com esse tipo <strong>de</strong> dados ou quando são aplicados a conjuntos <strong>de</strong> dados <strong>de</strong> pequena<br />

ou média dimensão.<br />

O algoritmo Multi-Way foi proposto por Zhao et al [Zhao1997] exactamente na sequência da ausência <strong>de</strong><br />

trabalhos nesta área. A i<strong>de</strong>ia básica <strong>de</strong>ste algoritmo resi<strong>de</strong> no aproveitamento das características<br />

inerentes a este tipo <strong>de</strong> sistemas, que pela sua própria organização dispensam a necessida<strong>de</strong> <strong>de</strong><br />

reor<strong>de</strong>nar atributos e efectuar agrupamentos <strong>de</strong> forma a que os primeiros agregados calculados possam<br />

servir <strong>de</strong> base ao cálculo <strong>de</strong> agregados posteriores: o truque consiste em percorrer os valores das<br />

dimensões, armazenados em posições fixas, da forma mais eficiente possível e calcular<br />

simultaneamente o máximo <strong>de</strong> agregados parciais espacialmente <strong>de</strong>limitados que for possível. O<br />

principal problema que se põe a esta abordagem está relacionado com a forma como os arrays vão ser<br />

geridos, uma vez que é necessário carregar e armazenar arrays que provavelmente ultrapassam a<br />

capacida<strong>de</strong> <strong>de</strong> memória existente. Para resolver os problemas <strong>de</strong> gestão <strong>de</strong> memória, os autores<br />

propuseram o uso <strong>de</strong> chunking, por forma a dividir arrays n-dimensionais em fragmentos n-dimensionais<br />

mais pequenos que po<strong>de</strong>m ser armazenados como um único objecto.<br />

Os princípios básicos <strong>de</strong>ste algoritmo, tais como a or<strong>de</strong>nação óptima, o chunking e a MMST, estiveram<br />

na base <strong>de</strong> um algoritmo <strong>de</strong>senvolvido e implementado por Tam [Tam1998], tal como explicado no<br />

<strong>de</strong>correr da secção anterior. Embora na prática o algoritmo se afaste do que foi proposto por Zhao et al,<br />

continua a ser um exemplo válido <strong>de</strong> uma implementação possível baseada nesse conjunto <strong>de</strong><br />

princípios, apesar <strong>de</strong> direccionada e optimizada para um fim específico. Porém, in<strong>de</strong>pen<strong>de</strong>ntemente dos<br />

bons resultados conseguidos, o algoritmo continua a apresentar limitações uma vez que apenas<br />

consegue computar cubos com pequena a média dimensão (com menos <strong>de</strong> <strong>de</strong>z dimensões) [Tam1998].<br />

Tendo em conta a escassez <strong>de</strong> trabalhos direccionados para sistemas MOLAP e os bons resultados<br />

alcançados por este algoritmo, consi<strong>de</strong>rou-se que seria interessante focar o trabalho sobre o algoritmo<br />

46


Multi-Way. Além do algoritmo proposto e do relatório do trabalho realizado por Tam, não existe qualquer<br />

outra informação disponível sobre este algoritmo, assim como não foi possível ter acesso à<br />

implementação realizada. Assim sendo, o objectivo <strong>de</strong>ste trabalho consiste em fazer um estudo<br />

aprofundado do algoritmo Multi-Way, com base na implementação realizada segundo a proposta <strong>de</strong><br />

[Zhao1997], e tentar introduzir nessa implementação optimizações que permitam ao algoritmo ser<br />

efectivo para maiores volumes <strong>de</strong> dados e maiores dimensionalida<strong>de</strong>s.<br />

3.2 Arquitectura<br />

Neste contexto, um cubo multidimensional é representado por dois vectores unidimensionais, em que um<br />

tem comprimento igual ao número <strong>de</strong> dimensões existentes nos dados e mantém em cada posição a<br />

cardinalida<strong>de</strong> da dimensão respectiva e o outro tem comprimento igual ao produto das cardinalida<strong>de</strong>s<br />

das dimensões envolvidas e mantém os valores computados. O vector que guarda a informação sobre<br />

as dimensões fá-lo obe<strong>de</strong>cendo à or<strong>de</strong>nação óptima <strong>de</strong>finida por Zhao et al [Zhao1997]. Esse vector<br />

funciona como um vector <strong>de</strong> controlo na medida em que permite recuperar os valores que estão<br />

guardados no outro vector, usando uma função <strong>de</strong> conversão. Assumindo que temos um cubo com 3<br />

dimensões |A| = 2, |B| = 3, |C| = 4 e preten<strong>de</strong>mos ace<strong>de</strong>r à posição (2, 1, 0) no vector <strong>de</strong> dados, a<br />

posição correspon<strong>de</strong>nte no vector unidimensional é dada pelo produto entre as cardinalida<strong>de</strong>s <strong>de</strong> cada<br />

uma das dimensões e a coor<strong>de</strong>nada que se preten<strong>de</strong> converter relativa a essa dimensão (2 + (3 x 1) +<br />

2 x 3 x 0 = 5). Esta abordagem permite que seja utilizado qualquer tipo <strong>de</strong> função <strong>de</strong> cálculo pois esta foi<br />

<strong>de</strong>finida a partir <strong>de</strong> uma classe genérica abstracta. Para tal, apenas é necessário <strong>de</strong>rivar uma classe<br />

específica para a função pretendida.<br />

No que se refere à forma como os dados são mantidos e utilizados pelo algoritmo, estes são mantidos<br />

numa tabela da base <strong>de</strong> dados que simula uma tabela <strong>de</strong> factos. Essa tabela é composta por um<br />

i<strong>de</strong>ntificador do agregado, uma coluna por dimensão que representa a posição relativa no agregado e o<br />

valor correspon<strong>de</strong>nte a essa posição para esse agregado. A tabela abaixo mostra uma utilização<br />

possível para essa tabela, assumindo que temos um cubo com as dimensões A, B e C em que |A| = |B| =<br />

|C| = 3. Ao lado <strong>de</strong> cada tuplo, está indicado o cubói<strong>de</strong> a que se refere. Como se po<strong>de</strong> verificar, existem<br />

várias entradas para o mesmo cubói<strong>de</strong>, na medida em que cada linha correspon<strong>de</strong> a uma posição<br />

diferente nesse cubói<strong>de</strong>. A necessida<strong>de</strong> do i<strong>de</strong>ntificador advém do facto <strong>de</strong> existirem entradas com<br />

valores iguais para diferentes cubói<strong>de</strong>s. Como exemplo, temos as linhas 7 e 15, em que os valores para<br />

as várias colunas são iguais (2, 0, 0, ..., 0) mas se referem a cubói<strong>de</strong>s diferentes (AB e BC<br />

respectivamente). Desta forma, consegue-se representar qualquer elemento <strong>de</strong> qualquer cubói<strong>de</strong>.<br />

47


Tabela 9 <strong>–</strong> Exemplo <strong>de</strong> notação utilizada para i<strong>de</strong>ntificar os agregados e seus elementos<br />

I<strong>de</strong>ntificador Col001 Col002 Col003 Col004 ... Col010 Valor<br />

AB L000001 0 0 0 0 ... 0 3<br />

AB L000001 0 1 0 0 ... 0 7<br />

AB L000001 0 2 0 0 ... 0 1<br />

AB L000001 1 0 0 0 ... 0 5<br />

AB L000001 1 1 0 0 ... 0 8<br />

AB L000001 1 2 0 0 ... 0 6<br />

AB L000001 2 0 0 0 ... 0 10<br />

AB L000001 2 1 0 0 ... 0 2<br />

AB L000001 2 2 0 0 ... 0 3<br />

AC L000002 0 0 0 0 ... 0 9<br />

AC L000002 0 0 0 0 ... 0 11<br />

... … ... ... … ... ... ... ...<br />

AC L000002 1 2 0 0 ... 0 13<br />

... … ... ... … ... ... ... ...<br />

BC L001002 2 0 0 0 ... 0 12<br />

... … ... ... … ... ... ... ...<br />

Actualmente, a tabela possui no máximo <strong>de</strong>z colunas, uma vez que as tabelas têm que ser construídas<br />

com um número limite <strong>de</strong> colunas. Porém, este valor não coloca qualquer limitação ao algoritmo na<br />

medida em que este não <strong>de</strong>pen<strong>de</strong> do número <strong>de</strong> colunas da tabela, que po<strong>de</strong> ser facilmente alterado,<br />

visto que recebe à partida o número <strong>de</strong> dimensões a tratar.<br />

3.3 Optimização <strong>de</strong> “sub-treeing”<br />

O conceito <strong>de</strong> árvore mínima <strong>de</strong> cobertura (MMST) para um <strong>de</strong>terminado or<strong>de</strong>namento das dimensões é<br />

central no algoritmo, uma vez que assegura que é alocada a quantida<strong>de</strong> mínima <strong>de</strong> memória necessária<br />

para esse or<strong>de</strong>namento das dimensões. A i<strong>de</strong>ia <strong>de</strong>sta optimização passa por optimizar o funcionamento<br />

do algoritmo quando se preten<strong>de</strong> calcular um <strong>de</strong>terminado agregado, uma vez que a topologia do próprio<br />

algoritmo obriga a refazer os cálculos sempre que é realizada um operação OLAP, como drill-down e roll-<br />

up. Logo, quando se preten<strong>de</strong> calcular um <strong>de</strong>terminado agregado, não há necessida<strong>de</strong> <strong>de</strong> calcular todos<br />

os agregados correspon<strong>de</strong>ntes a cada um dos nós da árvore mas somente aqueles que são estritamente<br />

necessários, ou seja, não é necessário calcular toda a árvore mas apenas uma porção <strong>de</strong>sta (sub-tree).<br />

A figura 25 mostra o pseudocódigo correspon<strong>de</strong>nte à implementação da MMST. Para que a árvore<br />

pu<strong>de</strong>sse suportar esta optimização, foi necessário planear uma forma <strong>de</strong> marcar os nós que são<br />

necessários para calcular um agregado por forma a que se distingam dos restantes e possam assim ser<br />

48


facilmente seleccionados para cálculo, o que é conseguido através <strong>de</strong> uma proprieda<strong>de</strong> que mantém em<br />

cada nó da árvore a referência do seu nó pai.<br />

noRaiz {D 1,D 2,...,D n}<br />

listaNos {}<br />

initMMSTree()<br />

listaFilhos {}<br />

genFilhos(noRaiz)<br />

genFilhos(ListaDimensões noPai)<br />

pai noPai<br />

i n<br />

para cada D i em noPai<br />

noFilho noPai excluindo D i<br />

se(not noFilho listaNos)<br />

listaNos listaNos noFilho<br />

listaFilhos listaFilhos noFilho<br />

genFilhos(noFilho)<br />

i i-1<br />

Figura 25 <strong>–</strong> Pseudocódigo correspon<strong>de</strong>nte à criação da MMST<br />

Para implementar esta optimização, é necessário recorrer a um mecanismo básico <strong>de</strong> <strong>de</strong>scoberta <strong>de</strong><br />

caminho (path finding) que permita assinalar quais os nós da árvore que é necessário calcular por forma<br />

a conseguir obter um <strong>de</strong>terminado agregado. Para este efeito, os nós são marcados <strong>de</strong>s<strong>de</strong> o nó<br />

objectivo (calculate = true) até à raiz. Para agilizar o varrimento da árvore, cada nó mantém uma<br />

referência para o nó pai imediatamente acima na árvore, à excepção do nó raiz em que o valor da<br />

proprieda<strong>de</strong> father é nulo.Um exemplo da utilida<strong>de</strong> <strong>de</strong>sta implementação po<strong>de</strong> ser facilmente<br />

concretizado, tendo em conta a MMST da figura 26. Segundo o algoritmo original, para calcular o valor<br />

<strong>de</strong> ALL é necessário calcular um total <strong>de</strong> quinze agregados antes <strong>de</strong> obter o valor <strong>de</strong> ALL, ou seja, é<br />

necessário calcular o valor dos agregados correspon<strong>de</strong>ntes a cada um dos nós da árvore. Utilizando<br />

sub-treeing, o valor do agregado ALL po<strong>de</strong> ser obtido calculando apenas quatro agregados uma vez que<br />

apenas é obrigatório calcular o valor correspon<strong>de</strong>nte aos nós ALL, A (father(ALL) = A), AB<br />

(father(A) = AB) e ABC (father(AB) = ABC).<br />

49


Figura 26 <strong>–</strong> Exemplo <strong>de</strong> uma MMST para O = (A, B, C, D)<br />

O objectivo <strong>de</strong>sta optimização passa por reduzir o número <strong>de</strong> nós que é necessário computar para obter<br />

um <strong>de</strong>terminado agregado <strong>de</strong> uma forma simples, o que terá impacto sobre o tempo necessário para<br />

computar esse agregado visto eliminar a computação <strong>de</strong> nós que não interferem directamente no cálculo.<br />

Esta optimização não tem qualquer correspondência no trabalho realizado por Tam [Tam1998] uma vez<br />

que este se baseia na MNST para gerir a sequência <strong>de</strong> computação dos agregados.<br />

3.4 Optimização <strong>de</strong> “sub-chunking”<br />

Tal como referido anteriormente, os arrays <strong>de</strong> gran<strong>de</strong>s dimensões <strong>de</strong>vem ser armazenados divididos em<br />

chunks, por questões <strong>de</strong> eficiência e <strong>de</strong>sempenho. Esta estratégia permite que todas as dimensões<br />

sejam tratadas <strong>de</strong> forma uniforme, uma vez que o chunking permite dividir um array n-dimensional em<br />

vários chunks n-dimensionais que po<strong>de</strong>m ser armazenados em disco.<br />

Um dos principais problemas que se coloca tanto a este algoritmo como aos restantes algoritmos da<br />

área é a quantida<strong>de</strong> <strong>de</strong> memória que requerem para po<strong>de</strong>r calcular os agregados. Em resultados dos<br />

testes efectuados à sua implementação, Tam refere que o seu algoritmo não conseguia completar os<br />

cálculos para volumes <strong>de</strong> dados superiores a 240000 tuplos com 6 dimensões, apenas conseguindo<br />

computar cubos com maior número <strong>de</strong> dimensões para menores volumes <strong>de</strong> dados [Tam1998].<br />

Tendo em conta a árvore da figura 26, verifica-se que o pior caso correspon<strong>de</strong> ao cálculo do agregado<br />

ABC, que necessita <strong>de</strong> um total <strong>de</strong> blocos <strong>de</strong> memória equivalente ao produto da cardinalida<strong>de</strong> das n-1<br />

primeiras dimensões segundo a or<strong>de</strong>m O (10 x 100 x 1000 = 1000000 blocos <strong>de</strong> memória). A solução<br />

passa por criar um sub-chunk mais pequeno recorrendo ao máximo divisor comum (MDC) das cardinalida<strong>de</strong>s<br />

das dimensões, o que para o exemplo anterior resultaria num total <strong>de</strong> 10 x 10 x 10 = 1000 blocos <strong>de</strong> memória.<br />

Desta forma, é necessário guardar para suporte persistente cada um dos sub-chunks para garantir que os<br />

resultados não são alterados e recuperar o sub-chunk pretendido quando se preten<strong>de</strong> mudar para outro. Isto<br />

50


acarreta forçosamente uma carga a nível <strong>de</strong> operações <strong>de</strong> entrada/saída que tem impacto na velocida<strong>de</strong> <strong>de</strong><br />

<strong>de</strong>sempenho do algoritmo, mas que é compensada pelo facto <strong>de</strong> se conseguir realizar cálculos que doutra<br />

forma não seriam fazíveis. O uso do MDC assegura que é criado o maior bloco possível e garante assim que é<br />

realizado o número mínimo possível <strong>de</strong> operações <strong>de</strong> leitura e escrita. Nos casos em que esta estratégia não<br />

permite ainda que o cálculo seja efectuado por falta <strong>de</strong> memória, é criado um novo sub-chunk cuja dimensão<br />

resulta do quociente entre o máximo divisor comum (MDC) e o mínimo divisor comum (mDC). No pior dos<br />

casos, cada um dos novos sub-chunks correspon<strong>de</strong>rá a 1 bloco <strong>de</strong> memória, mais uma vez assegurando que<br />

o cálculo po<strong>de</strong> ser efectuado em <strong>de</strong>trimento do <strong>de</strong>sempenho.<br />

Convém sublinhar que todo este processo não altera em nada a lógica <strong>de</strong> funcionamento do algoritmo tal<br />

como foi proposto, uma vez que a necessida<strong>de</strong> <strong>de</strong> mudança <strong>de</strong> um sub-chunk para outro é gerida pelo próprio<br />

nó da MMST: cada nó conhece a dimensão do seu sub-chunk e a base actual e sempre que <strong>de</strong>tecta que o<br />

elemento a tratar está fora do âmbito do sub-chunk em memória or<strong>de</strong>na o carregamento do sub-chunk<br />

a<strong>de</strong>quado.<br />

dim {D 1,D 2,...,D n}<br />

maxDC MDC(dim)<br />

mDC mDC(dim)<br />

chunk maxDC<br />

tam D 1 x D 2 x ... x D n-1<br />

MAX número máximo <strong>de</strong> blocos <strong>de</strong> memória possível<br />

base {b 1,b 2,...,b n}<br />

loc {l 1,l 2,...,l n}<br />

enquanto(tam > MAX)<br />

chunk maxDC/mDC<br />

tam chunk n-1<br />

para cada D i em loc<br />

se(l i > b i l i < b i)<br />

guardaSubChunk(loc)<br />

lêSubChunk(loc)<br />

actualiza(loc,val)<br />

Figura 27 - Pseudocódigo que ilustra o mecanismo <strong>de</strong> sub-chunking<br />

51


4 Estudo do algoritmo Multi-Way<br />

Esta secção <strong>de</strong>screve os resultados obtidos na sequência do estudo do algoritmo Multi-Way, incluindo<br />

também os efeitos das optimizações propostas na secção 3. Para realizar o estudo, foram realizados<br />

testes no sentido <strong>de</strong> avaliar a influência da <strong>de</strong>nsida<strong>de</strong> dos dados e do volume dos dados sobre o<br />

algoritmo com e sem as optimizações propostas. A nível da análise da influência do volume <strong>de</strong> dados,<br />

foram ainda estudados dois níveis <strong>de</strong> variação diferentes <strong>de</strong>vido à natureza específica do problema, ou<br />

seja, o volume <strong>de</strong> dados submetidos ao algoritmo foi variado tanto em termos do número <strong>de</strong> dimensões<br />

existentes como em termos do número <strong>de</strong> valores comportados por cada dimensão. Na sequência dos<br />

testes, foram recolhidos dados sobre o número <strong>de</strong> leituras e escritas realizadas na base <strong>de</strong> dados, o<br />

tempo <strong>de</strong> execução total e individualizado para cada etapa do algoritmo e o número <strong>de</strong> nós da estrutura<br />

base explorados para realizar o cálculo do cubo.<br />

4.1 Dados <strong>de</strong> teste<br />

Os dados utilizados para realizar o estudo do algoritmo foram gerados recorrendo ao projecto Illimine 2 .<br />

Trata-se <strong>de</strong> um projecto mantido pelo grupo <strong>de</strong> pesquisa em exploração <strong>de</strong> dados (data mining) da<br />

<strong>Universida<strong>de</strong></strong> <strong>de</strong> Illinois li<strong>de</strong>rado pelo professor Jiawei Han que reúne diversas ferramentas nas áreas <strong>de</strong><br />

data mining e aprendizagem, disponibilizando mesmo via internet <strong>de</strong>monstrações <strong>de</strong> alguns dos<br />

principais algoritmos nessa área. Igualmente disponibilizado por este projecto está um gerador aleatório<br />

<strong>de</strong> dados, no qual o utilizador po<strong>de</strong> especificar o número <strong>de</strong> transacções que preten<strong>de</strong>, o número <strong>de</strong><br />

dimensões e a cardinalida<strong>de</strong> <strong>de</strong> cada dimensão.<br />

Seguidamente, foi <strong>de</strong>finido um plano <strong>de</strong> testes que nos permitisse avaliar os aspectos referidos<br />

anteriormente, nomeadamente a influência da <strong>de</strong>nsida<strong>de</strong> e quantida<strong>de</strong> <strong>de</strong> dados submetidos ao<br />

algoritmo, tal como mostra a tabela abaixo. Cada um dos testes, à execpção dos testes T1 a T4<br />

inclusivé, foi executado para a implementação realizada do algoritmo original (MW), para a<br />

implementação com cada uma das optimizações propostas (MW + SC e MW + ST) e para a<br />

implementação reunindo as duas optimizações (MW + SC + ST). Em cada um dos testes, proce<strong>de</strong>u-se<br />

ao cálculo do agregado ALL por forma a forçar o algoritmo a percorrer o maior número possível <strong>de</strong> níveis<br />

da MMST e utilizar o maior bloco <strong>de</strong> memória necessário para efectuar esse cálculo.<br />

2 http://illimine.cs.uiuc.edu<br />

52


Tabela 10 <strong>–</strong> Plano <strong>de</strong> testes<br />

Teste Nº <strong>de</strong> transacções Dimensões Cardinalida<strong>de</strong>s<br />

T1 60000 4 10 20 30 40<br />

T2 120000 4 10 20 30 40<br />

T3 180000 4 10 20 30 40<br />

T4 240000 4 10 20 30 40<br />

T5 5000 3 10 10 10<br />

T6 5000 4 10 10 10 10<br />

T7 5000 5 10 10 10 10 10<br />

T8 5000 3 10 10 10<br />

T9 5000 3 20 20 20<br />

T10 5000 3 30 30 30<br />

T11 5000 3 40 40 40<br />

T12 5000 3 50 50 50<br />

T13 5000 3 60 60 60<br />

T14 5000 3 70 70 70<br />

T15 5000 3 80 80 80<br />

T16 5000 3 90 90 90<br />

Em seguida apresentam-se os resultados obtidos após a concretização do plano <strong>de</strong> testes apresentado<br />

na tabela 9, assim como a análise dos mesmos. Os testes foram realizados num Pentium IV a 3Ghz com<br />

1 Gb <strong>de</strong> memória, com sistema operativo Windows XP Professional.<br />

4.2 Estudo do efeito da variação na <strong>de</strong>nsida<strong>de</strong> dos dados<br />

Para avaliar o impacto da variação da <strong>de</strong>nsida<strong>de</strong> dos dados no <strong>de</strong>sempenho do algoritmo, foram<br />

realizados os testes T1 a T4. Como se po<strong>de</strong> observar tendo em atenção as características dos ficheiros<br />

utilizados, todos eles apresentam o mesmo número <strong>de</strong> dimensões com a mesma cardinalida<strong>de</strong>. A<br />

variação na <strong>de</strong>nsida<strong>de</strong> foi conseguida variando o número <strong>de</strong> transacções consi<strong>de</strong>radas. Os ficheiros<br />

para os testes T1, T2 e T3 foram <strong>de</strong>pois obtidos usando uma percentagem crescente do número máximo<br />

<strong>de</strong> transacções dado pelo produto das cardinalida<strong>de</strong>s das dimensões (10 x 20 x 30 x 40 = 240000),<br />

respectivamente 25%, 50% e 75% <strong>de</strong>sse valor. O gráfico abaixo mostra os resultados obtidos para os<br />

testes T1 a T4 no que se refere ao número total <strong>de</strong> leituras e escritas realizadas na base <strong>de</strong> dados pela<br />

implementação do algoritmo original.<br />

53


T4<br />

T3<br />

T2<br />

T1<br />

0 50000 100000 150000 200000 250000 300000 350000<br />

Figura 28 <strong>–</strong> Efeito da variação da <strong>de</strong>nsida<strong>de</strong> dos dados no número <strong>de</strong> leituras e escritas efectuadas por MW<br />

Como se po<strong>de</strong> constatar da observação do gráfico, in<strong>de</strong>pen<strong>de</strong>ntemente da <strong>de</strong>nsida<strong>de</strong> dos dados, o<br />

algoritmo efectua sempre o mesmo número <strong>de</strong> operações <strong>de</strong> leitura e escrita. Embora este facto possa à<br />

partida parecer <strong>de</strong>sconcertante, <strong>de</strong>corre da própria lógica <strong>de</strong> funcionamento do algoritmo, já que é feito<br />

um varrimento <strong>de</strong> todas as dimensões, começando na dimensão <strong>de</strong> maior cardinalida<strong>de</strong>, e visitadas<br />

todas as posições, uma vez que não se dispõe <strong>de</strong> qualquer informação sobre o seu conteúdo.<br />

Consequentemente, o número <strong>de</strong> operações <strong>de</strong> leitura e escrita realizadas pelo algoritmo apenas<br />

<strong>de</strong>pen<strong>de</strong> do produto das cardinalida<strong>de</strong>s das dimensões envolvidas, <strong>de</strong>s<strong>de</strong> que os dados apresentem o<br />

mesmo número <strong>de</strong> dimensões . O mesmo raciocínio se aplica ao gráfico da figura 29, que apresenta os<br />

tempos <strong>de</strong> cálculo do cubo para diferentes <strong>de</strong>nsida<strong>de</strong>s dos dados <strong>de</strong> entrada.<br />

00:02:44<br />

00:02:26<br />

00:02:09<br />

00:01:52<br />

00:01:35<br />

00:01:17<br />

00:01:00<br />

T1 T2 T3 T4<br />

Escritas<br />

Leituras<br />

Figura 29 <strong>–</strong> Efeito da variação da <strong>de</strong>nsida<strong>de</strong> dos dados no tempo usado por MW para calcular o cubo<br />

54


Uma vez que as restantes implementações do algoritmo seguem a mesma filosofia por se basearem<br />

nele, as conclusões obtidas seriam exactamente as mesmas no que se refere à influência da <strong>de</strong>nsida<strong>de</strong><br />

dos dados no <strong>de</strong>sempenho do algoritmo.<br />

4.3 Estudo do efeito da variação do volume <strong>de</strong> dados<br />

A variação do volume <strong>de</strong> dados po<strong>de</strong> ser consequência da variação do número <strong>de</strong> dimensões que<br />

compõem os dados ou da variação da cardinalida<strong>de</strong> das dimensões envolvidas, pelo que é necessário<br />

analisar cada uma das situações separadamente.<br />

4.3.1 Efeito da variação do número <strong>de</strong> dimensões<br />

Para avaliar o impacto da variação da <strong>de</strong>nsida<strong>de</strong> dos dados no <strong>de</strong>sempenho do algoritmo, foram<br />

realizados os testes T5 a T7, cujos resultados são apresentados <strong>de</strong> seguida. O gráfico 30 apresenta os<br />

resultados dos testes para o algoritmo MW, enquanto os gráficos 31 e 32 fazem o comparativo entre os<br />

resultados obtidos para as diferentes implementações.<br />

180000<br />

160000<br />

140000<br />

120000<br />

100000<br />

80000<br />

60000<br />

40000<br />

20000<br />

0<br />

T5 T6 T7<br />

Leituras 1330 14640 161050<br />

Escritas 836 9596 66006<br />

Figura 30 <strong>–</strong> Efeito da variação do número <strong>de</strong> dimensões nas leituras e escritas realizadas para o algoritmo MW<br />

55


250000<br />

200000<br />

150000<br />

100000<br />

50000<br />

0<br />

T5 T6 T7<br />

MW 1330 14640 161050<br />

MW+ST 1110 11110 111110<br />

MW+SC 1330 14640 226210<br />

MW+ST+SC 1110 11110 124960<br />

140000<br />

120000<br />

100000<br />

80000<br />

60000<br />

40000<br />

20000<br />

0<br />

Leituras<br />

Escritas<br />

T5 T6 T7<br />

MW 836 9596 66006<br />

MW+ST 616 6066 16066<br />

MW+SC 836 9596 126211<br />

MW+ST+SC 616 6066 24961<br />

Figura 31 <strong>–</strong> Efeito da variação do número <strong>de</strong> dimensões nas leituras e escritas realizadas<br />

Como se po<strong>de</strong> verificar da observação dos gráficos, o número <strong>de</strong> leituras e escritas aumenta quando<br />

aumenta o número <strong>de</strong> dimensões consi<strong>de</strong>radas. Porém, esta variação é explicada pelo facto <strong>de</strong>, quando<br />

existem mais dimensões, existem consequentemente mais agregados, que por sua vez correspon<strong>de</strong>m a<br />

um maior número <strong>de</strong> nós na MMST. Da mesma forma, é possível observar que, sempre que se utilize<br />

sub-treeing (ST), o número <strong>de</strong> leituras e escritas é inferior ao verificado para a implementação original,<br />

uma vez que o objectivo <strong>de</strong>sta optimização é exactamente diminuir o número <strong>de</strong> nós que é necessário<br />

explorar para calcular um <strong>de</strong>terminado agregado, reduzindo consequentemente esse tipo <strong>de</strong> operações.<br />

Adicionalmente, verifica-se que sempre que se utiliza apenas sub-chunking (SC) há um aumento no<br />

número <strong>de</strong> leituras e escritas, que advém do facto <strong>de</strong> ser necessário subdividir blocos <strong>de</strong> memória e isso<br />

implicar um maior número <strong>de</strong> leituras e escritas intermédias na base <strong>de</strong> dados para se computar o<br />

mesmo agregado. Quando as duas optimizações são utilizadas em conjunto, verifica-se uma melhoria<br />

56


em relação ao original mas uma <strong>de</strong>terioração em relação à implementação que apenas utiliza sub-<br />

treeing.<br />

Outra medida com interesse para o estudo do efeito da variação do número <strong>de</strong> dimensões correspon<strong>de</strong> à<br />

contabilização dos nós da MMST que são explorados por cada uma das implementações do algoritmo.<br />

As figuras 32 e 33 mostram o efeito da variação do número <strong>de</strong> dimensões no número <strong>de</strong> nós explorados<br />

para o algoritmo MW e para as diferentes implementações, respectivamente.<br />

35<br />

30<br />

25<br />

20<br />

15<br />

10<br />

5<br />

0<br />

T5 T6 T7<br />

MW 8 16 32<br />

Figura 32 - Efeito da variação do número <strong>de</strong> dimensões no número <strong>de</strong> nós da MMST explorados para o algoritmo MW<br />

35<br />

30<br />

25<br />

20<br />

15<br />

10<br />

5<br />

0<br />

T5 T6 T7<br />

MW 8 16 32<br />

MW+ST 4 5 6<br />

MW+SC 8 16 32<br />

MW+SC+ST 4 5 6<br />

Figura 33 <strong>–</strong> Efeito da variação do número <strong>de</strong> dimensões no número <strong>de</strong> nós da MMST explorados<br />

Verifica-se facilmente, tal como seria esperado, que a um maior número <strong>de</strong> dimensões nos dados<br />

correspon<strong>de</strong> igualmente um maior número <strong>de</strong> nós da MMST explorados, tal como referimos na análise<br />

57


dos gráficos anteriores. Esse acréscimo é mais acentuado nas implementações que não empregam<br />

sub-treeing, o que confirma novamente o que havíamos constatado na análise do gráfico anterior.<br />

O gráfico seguinte ilustra a influência do aumento do número <strong>de</strong> dimensões no tempo necessário para o<br />

algoritmo calcular o agregado ALL. Como se po<strong>de</strong> verificar, o tempo dispendido nesse cálculo aumenta<br />

com o número <strong>de</strong> dimensões envolvidas, o que confirma igualmente os resultados apresentados por<br />

Tam [Tam1998].<br />

00:02:01<br />

00:01:44<br />

00:01:26<br />

00:01:09<br />

00:00:52<br />

00:00:35<br />

00:00:17<br />

00:00:00<br />

Figura 34 <strong>–</strong> Efeito da variação do número <strong>de</strong> dimensões no tempo <strong>de</strong> cálculo do cubo<br />

É vísivel que o tempo <strong>de</strong> execução do algoritmo é sempre superior para as implementações que<br />

empregam a optimização <strong>de</strong> sub-chunking, o que seria expectável. Para volumes <strong>de</strong> dados menores,<br />

essas alterações não são tão notórias, tornando-se mais vísiveis para volumes <strong>de</strong> dados maiores.<br />

Verifica-se também que o <strong>de</strong>sempenho é inferior quando se utiliza apenas sub-chunking do que quando<br />

se utilizam ambas as optimizações. Isto <strong>de</strong>ve-se ao facto <strong>de</strong> a introdução do sub-treeing apenas trazer<br />

benefícios a nível do <strong>de</strong>sempenho, na medida em que permite reduzir o número <strong>de</strong> nós explorados na<br />

árvore, mas a introdução do sub-chunking gerar uma <strong>de</strong>gradação a nível do <strong>de</strong>sempenho do algoritmo,<br />

na medida em que o facto <strong>de</strong> ser necessário subdividir blocos <strong>de</strong> memória implica um maior número <strong>de</strong><br />

leituras e escritas na base <strong>de</strong> dados, tal como comprovado nos gráficos 30 e 31.<br />

4.3.2 Efeito da variação da cardinalida<strong>de</strong> das dimensões<br />

Para avaliar o impacto da variação da <strong>de</strong>nsida<strong>de</strong> dos dados no <strong>de</strong>sempenho do algoritmo, foram<br />

realizados os testes T8 a T16. Tendo em conta o objectivo <strong>de</strong>stes testes, não são apresentados<br />

resultados relativos ao número <strong>de</strong> nós explorados visto que, tal como mostrámos na secção 4.2, o<br />

número <strong>de</strong> nós explorados mantém-se constante <strong>de</strong>s<strong>de</strong> que o número <strong>de</strong> dimensões envolvidas seja o<br />

mesmo, que se verifica nesta situação.<br />

MW MW+ST MW+SC MW+ST+SC<br />

T5<br />

T6<br />

T7<br />

58


As figuras 35 e 36 mostram o efeito da variação da cardinalida<strong>de</strong> das dimensões no número <strong>de</strong> leituras e<br />

escritas realizadas pelo algoritmo para diferentes optimizações, respectivamente.<br />

1000000<br />

100000<br />

10000<br />

1000<br />

100<br />

10<br />

1<br />

T8 T9 T10 T11 T12 T13 T14 T15 T16<br />

MW 1330 9260 29790 68920 132650 226980 357910 531440 571280<br />

MW+ST 1110 8420 27930 65640 127550 219660 347970 518480 538880<br />

MW+SC 1330 9260 31710 72280 183050 249660 453670 571280 753570<br />

MW+SC+ST 1110 8420 28920 67360 155000 231360 399000 538880 737190<br />

Figura 35 <strong>–</strong> Efeito da variação da cardinalida<strong>de</strong> das dimensões no número <strong>de</strong> leituras efectuadas<br />

1000000<br />

100000<br />

10000<br />

1000<br />

100<br />

10<br />

1<br />

Leituras<br />

Escritas<br />

T8 T9 T10 T11 T12 T13 T14 T15 T16<br />

MW 836 3238 5766 7896 10626 13956 17886 22416 59281<br />

MW+ST 616 2398 3906 4616 5526 6636 7946 9456 26881<br />

MW+SC 836 3238 4711 8281 58051 33661 110671 59281 27546<br />

MW+SC+ST 616 2398 1921 3361 30001 15361 56001 26881 11166<br />

Figura 36 - Efeito da variação da cardinalida<strong>de</strong> das dimensões no número <strong>de</strong> escritas efectuadas<br />

Constata-se que, à medida que aumenta a cardinalida<strong>de</strong> das dimensões envolvidas, o número <strong>de</strong><br />

leituras e escritas aumenta também drasticamente, sendo o acréscimo no número <strong>de</strong> leituras sempre<br />

59


superior ao aumento do número <strong>de</strong> escritas. Mantem-se a tendência verificada nos testes anteriores, em<br />

que a implementação que apenas emprega sub-treeing realiza um menor número <strong>de</strong> leituras e escritas e<br />

a implementação que apenas usa sub-chunking realiza mais leituras e escritas que o algoritmo original.<br />

Contudo, verifica-se que o uso conjunto das duas implementações implica um número <strong>de</strong> leituras e<br />

escritas inicialmente próximo do da implementação original mas, à medida que aumenta a cardinalida<strong>de</strong><br />

das dimensões, passa a realizar um maior número <strong>de</strong>stas operações quando comparada com a<br />

implementação original ou a que utiliza apenas sub-treeing.<br />

Estes resultados levantam a questão <strong>de</strong> qual a verda<strong>de</strong>ira utilida<strong>de</strong> <strong>de</strong>stas optimizações, se na prática<br />

conduzem à realização <strong>de</strong> um maior número <strong>de</strong> operações <strong>de</strong> leitura e escrita e , consequentemente, a<br />

maiores tempos <strong>de</strong> execução do algoritmo. O gráfico abaixo respon<strong>de</strong> a esta questão, ao mostrar que a<br />

partir <strong>de</strong> um <strong>de</strong>terminado volume <strong>de</strong> dados (2 560 000 tuplos com 4 dimensões) o algoritmo original não<br />

consegue efectuar o cálculo do agregado. Esta situação verificava-se igualmente na implementação <strong>de</strong><br />

Tam [Tam1998], que não conseguia completar os cálculos para volumes <strong>de</strong> dados superiores a 240000<br />

tuplos com 6 dimensões.<br />

00:23:02<br />

00:20:10<br />

00:17:17<br />

00:14:24<br />

00:11:31<br />

00:08:38<br />

00:05:46<br />

00:02:53<br />

00:00:00<br />

MW MW+ST MW+SC MW+SC+ST<br />

Figura 37 <strong>–</strong> Tempo consumido no cálculo do agregado pelas diferentes implementações para 2560000 tuplos<br />

Como se po<strong>de</strong> observar, o algoritmo original e a implementação que apenas emprega sub-treeing<br />

apresentam um tempo <strong>de</strong> cálculo igual a 0, o que na prática significa que não conseguiram efectuar o<br />

cálculo por falta <strong>de</strong> memória. Apenas as implementações que realizam sub-chunking conseguiram<br />

computar o agregado com sucesso, apresentando a implementação que emprega ambas as<br />

optimizações um <strong>de</strong>sempenho melhor. Com efeito, foi esta a razão pela qual foram <strong>de</strong>senvolvidas e<br />

introduzidas as optimizações referidas: apesar <strong>de</strong> não contribuirem para o <strong>de</strong>sempenho do algoritmo<br />

quando comparado com a sua versão original, são <strong>de</strong>cisivas no sentido em que permitem efectuar<br />

cálculos em situações em que o algoritmo original não consegue respon<strong>de</strong>r.<br />

60


Por fim, o gráfico da figura 38 mostra o efeito da variação da cardinalida<strong>de</strong> das dimensões no tempo <strong>de</strong><br />

cálculo do cubo. Para qualquer uma das implementações, a tendência é para um crescimento<br />

exponencial do tempo utilizado para calcular o cubo. Essa tendência é mais clara para a implementação<br />

original quando comparada com a implementação que apenas emprega sub-chunking.<br />

00:04:19<br />

00:03:36<br />

00:02:53<br />

00:02:10<br />

00:01:26<br />

00:00:43<br />

00:00:00<br />

Figura 38 <strong>–</strong> Efeito da variação da cardinalida<strong>de</strong> das dimensões no tempo <strong>de</strong> cálculo do cubo<br />

Os tempos <strong>de</strong> execução para esta implementação do algoritmo são afectados pelo facto <strong>de</strong> ser<br />

necessário diminuir o tamanho do sub-chunk à medida que aumenta o volume <strong>de</strong> dados, o que acarreta<br />

a realização <strong>de</strong> um maior número <strong>de</strong> leituras e escritas e se reflecte na forma mais ―aci<strong>de</strong>ntada‖ da<br />

curva. Esta causalida<strong>de</strong> é comprovada pelos gráficos das figuras 39 e 40.<br />

800000<br />

700000<br />

600000<br />

500000<br />

400000<br />

300000<br />

200000<br />

100000<br />

0<br />

T8 T9 T10 T11 T12 T13 T14 T15 T16<br />

T8 T9 T10 T11 T12 T13 T14 T15 T16<br />

Figura 39- Comparação entre as leituras realizadas para diferentes cardinalida<strong>de</strong>s <strong>de</strong> dimensões<br />

MW<br />

Leituras<br />

MW<br />

MW+ST<br />

MW+ST<br />

MW+SC<br />

MW+SC+ST<br />

61


120000<br />

100000<br />

80000<br />

60000<br />

40000<br />

20000<br />

0<br />

T8 T9 T10 T11 T12 T13 T14 T15 T16<br />

Escritas<br />

Figura 40 <strong>–</strong> Comparação entre as escritas realizadas para diferentes cardinalida<strong>de</strong>s <strong>de</strong> dimensões<br />

MW<br />

MW+ST<br />

MW+SC<br />

MW+SC+ST<br />

62


5 Balanço final<br />

O objectivo do presente trabalho consistiu em realizar um estudo <strong>de</strong>talhado do algoritmo Multi-Way,<br />

assim como das optimizações propostas por forma a que este pu<strong>de</strong>sse ser aplicado com sucesso a<br />

gran<strong>de</strong>s volumes <strong>de</strong> dados, o que não era possível com a sua implementação tal como proposto.<br />

Infelizmente, não foi possível ter acesso a outras implementações como forma <strong>de</strong> estabelecer mais<br />

comparações, estando apenas disponíveis o artigo <strong>de</strong> proposta do algoritmo Multi-Way [Zhao1997] e o<br />

relatório do trabalho realizado por Tam [Tam1998], no qual é <strong>de</strong>scrita uma variante do algoritmo<br />

disponibilizado no sistema DBMiner. Como tal, optou-se por implementar o algoritmo original e,<br />

adicionalmente, duas optimizações no sentido <strong>de</strong> fazer com que o algoritmo pu<strong>de</strong>sse computar cubos a<br />

partir <strong>de</strong> gran<strong>de</strong>s volumes <strong>de</strong> dados. As optimizações propostas foram as seguintes:<br />

A optimização <strong>de</strong>signada como sub-treeing, que está relacionada com a estrutura <strong>de</strong> dados<br />

básica do algoritmo (MMST) e que permite que o algoritmo explore um número menor <strong>de</strong> nós, o<br />

que provoca um acréscimo no <strong>de</strong>sempenho do mesmo<br />

A optimização <strong>de</strong>signada como sub-chunking, que altera ligeiramente uma das estratégias<br />

adoptadas pelo algoritmo para gerir o tamanho dos arrays <strong>de</strong> forma a que seja sempre<br />

aplicável, in<strong>de</strong>pen<strong>de</strong>ntemente da dimensão dos dados e da memória existente. Porém, como<br />

consequência <strong>de</strong>sta optimização, o algoritmo necessita <strong>de</strong> realizar operações <strong>de</strong> leitura e<br />

escritas adicionais sobre a base <strong>de</strong> dados, o que resulta num <strong>de</strong>créscimo do <strong>de</strong>sempenho.<br />

Assim, verifica-se que apesar da aplicação conjunta das duas optimizações não aumentar o<br />

<strong>de</strong>sempenho do algoritmo, a sua aplicação tem um impacto <strong>de</strong>cisivo a nível do seu potencial. Isto <strong>de</strong>ve-<br />

se fundamentalmente ao facto <strong>de</strong> que as optimizações propostas tornam possível a execução do<br />

algoritmo em situações nas quais, tanto a sua implementação original como a variante proposta por Tam,<br />

não conseguem obter resultados por falta <strong>de</strong> memória.<br />

63


6 Referências<br />

[Agrawal1994] Agrawal, Rakesh; Ramakrishnam Srikant. ―Fast Algorithms for Mining Association Rules.‖<br />

Proceedings of the 20th International Conference on VLDB. Santiago, 1994<br />

[Agrawal1996] Agrawal, Sameet, et al. ―On The Computation of Multidimensional Aggregates.‖<br />

Proceeddings of the 22nd VLDB Conference, pp. 506-521, 1996<br />

[Beyer1999] Beyer, Kevin; Raghu Ramakrishnam. ―Bottom-Up Computation of Sparse and Iceberg<br />

CUBEs.‖ Proceedings of ACM SIGMOD, 1999<br />

[Chauduri1997] Chanduri, Surajit; Umeshwar Dayal. ―An Overview of Data Warehousing and OLAP<br />

Technology.‖ ACM SIGMOD Record 26, n.º 1, pp. 65-74, 1997<br />

[Gray1997] Gray, Jim, Surajit Chaduri, Adam Bosworth, Andrew Layman, Don Reichart; Murali<br />

Venkatrao. ―Data Cube: A Relational Aggregation Operator Generalizing Group-By, Cross-Tab and Sub-<br />

Totals.‖ Journal of Data Mining and Knowledge Discovery 1, n.º 1, pp. 29—53, 1997<br />

[Han1999] Han, Jiawei, Jian Pei, e Yiwen Yin. ―Mining Frequent Patterns Without Candidate Generation.‖<br />

Technical Report TR-99-12, Department of Computer Science, Simon Fraser University, 1999<br />

[Han2001a] Han, Jiawei; Micheline Kamber. Data Mining: Concepts and Techniques. Morgan Kaufmann,<br />

2001<br />

[Han2001b] Han, Jiawei, Jian Pei, Guozhu Dong, e Ke Wang. ―Efficient Computation of Iceberg Cubes<br />

With Complex Measures.‖ Proceedings of the International Conference on Management of Data, 2001<br />

[Harinarayan1996] Harinarayan, Venkv; Anand Rajaraman; Jeffrey D. Ullman. ―Implementing Data Cubes<br />

Efficiently‖ Proceedings of ACM-SIGMOD International Conference on Management of Data, Montréal,<br />

pp. 205—216, 1996<br />

[Inmon1996] Inmon, W. H.; ―Building the Data Warehouse‖, John Wiley & Sons, New York, 1996<br />

[Ross1997] Ross, Kenneth A.; Divesh Srivastava. ―Fast Computation of Sparse Datacubes‖. Proceedings<br />

of 23rd VLDB Conference, Atenas, pp. 116—125, 1997<br />

[Tam1998] Tam, Yin Jenny. ―Datacube: Its Implementation and Application in OLAP Mining.‖ MSC tese,<br />

Simon Fraser University, 1998<br />

[Xin 2003] Xin, Dong; Jiawei Han; Xiao Lei Li; Benjamin W. Wah. ―Star-Cubing: Computing Iceberg<br />

Cubes by Top-Down and Bottom-Up Integration‖ Berlim, 2003<br />

64


[Zhao1997] Zhao, Yihong; Prasad M. Deshpan<strong>de</strong>; Jeffrey F. Naughton. ―An Array Based Algorithm for<br />

Simultaneous Multidimensional Aggregates‖. Proceedings of ACM-SIGMOD International Conference on<br />

Management of Data, Tucson, pp. 159—170, 1997<br />

65

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!