66
Setembro 2007 Algoritmos para a Geração de Hipercubos Análise do algoritmo Multi-Way RUI MANUEL CARVALHO DOS SANTOS CHAPOUTO Dissertação para obtenção do Grau de Mestre em ENGENHARIA INFORMÁTICA E DE COMPUTADORES Júri Presidente: Prof. Pedro Manuel Moreira Vaz Antunes de Sousa Orientador: Profª Cláudia Martins Antunes Vogais: Prof. Arlindo Manuel Limede de Oliveira Profª. Helena Isabel de Jesus Galhardas

Algoritmos para a Geração de Hipercubos

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Algoritmos para a Geração de Hipercubos

Setembro 2007

Algoritmos para a Geração de Hipercubos

Análise do algoritmo Multi-Way

RUI MANUEL CARVALHO DOS SANTOS CHAPOUTO

Dissertação para obtenção do Grau de Mestre em

ENGENHARIA INFORMÁTICA E DE COMPUTADORES

Júri

Presidente: Prof. Pedro Manuel Moreira Vaz Antunes de Sousa

Orientador: Profª Cláudia Martins Antunes

Vogais: Prof. Arlindo Manuel Limede de Oliveira

Profª. Helena Isabel de Jesus Galhardas

2 cm

2 cm

Page 2: Algoritmos para a Geração de Hipercubos

1

Agradecimentos

Gostaria de agradecer a todas as pessoas que, de alguma forma, directa ou indirectamente, contribuiram

com comentários ou sugestões no desenvolvimento desta tese.

À minha orientadora, prof. Cláudia Antunes, a disponibilidade apresentada ao longo dos anos de

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

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

deste projecto.

Aos meus colegas de trabalho, pelo incentivo e paciência nas inúmeras vezes em que abordei o assunto

deste trabalho ao longo destes anos.

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

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

incondiconal, o meu agradecimento muito especial.

Page 3: Algoritmos para a Geração de Hipercubos

2

Resumo

A tecnologia OLAP permite a um utilizador extrair e visualizar informação a partir de um conjunto de

dados de forma relativamente fácil e intuitiva, sob diferentes pontos de vista. Tipicamente, esta

tecnologia é aplicada a nível dos sistemas de apoio à decisão para produção de relatórios de negócios,

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

apresentação de diferentes vistas sobre os dados, as operações OLAP apoiam-se num modelo

multidimensional com base no qual é construída uma ―imagem‖ dos dados, designada como cubo. A

construção deste cubo implica o cálculo de agregados de dados multidimensionais, o que é uma tarefa

com elevados requisitos a nível de tempo e espaço e para a qual foram desenvolvidos diferentes

algoritmos. Um desses algoritmos é o algoritmo Multi-Way, que se destaca dos restantes no sentido de

ter sido originalmente concebido para sistemas MOLAP, para os quais existem poucos algoritmos, e de

ter alcançado níveis de desempenho bastante bons. O objectivo deste trabalho passa por estudar esse

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

consegue resolver, tais como a deficiente gestão de memória.

Palavras-chave: business intelligence, OLAP, modelo multidimensional, agregação

Page 4: Algoritmos para a Geração de Hipercubos

3

Abstract

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

intuitive way, from different perspectives. Usually, this technology is used in decision support system for

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

different perspectives is due to the fact that OLAP operations use a multidimensional model to build an

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

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

motivated the development of various algorithms, like Multi-Way algorithm. This algorithm was one of the

few developed for MOLAP systems and shows good performances when compared with algorithms that

follow other approaches. The goal of this thesis is to study that algorithm and develop optimizations that

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

Key words: business intelligence, OLAP, multidimensional model, aggregation

Page 5: Algoritmos para a Geração de Hipercubos

4

Índice

Lista de figuras .............................................................................................................................................. 6

Lista de tabelas ............................................................................................................................................. 8

Lista de abreviaturas ..................................................................................................................................... 9

1 Introdução ........................................................................................................................................... 10

1.1 Motivação .................................................................................................................................... 11

1.2 Objectivo da tese ........................................................................................................................ 11

1.3 Estrutura da tese ......................................................................................................................... 11

2 Trabalhos prévios sobre geração de hipercubos ................................................................................ 13

2.1 Modelo de dados multidimensional ............................................................................................. 13

2.2 O operador DATA CUBE ............................................................................................................ 18

2.3 Selecção de agregados para pré-computação ........................................................................... 21

2.4 Computação de agregados multidimensionais ........................................................................... 22

2.4.1 Algoritmos baseados em ordenação e dispersão (sorting e hashing) ................................ 23

2.4.2 Algoritmos baseados em partição ....................................................................................... 27

2.4.3 Algoritmos baseados em arrays .......................................................................................... 29

2.5 Variantes ao problema tradicional............................................................................................... 42

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

2.5.2 H-cubing .............................................................................................................................. 43

2.5.3 Star-Cubing ......................................................................................................................... 44

3 Trabalho realizado .............................................................................................................................. 46

3.1 Motivação .................................................................................................................................... 46

3.2 Arquitectura ................................................................................................................................. 47

3.3 Optimização de ―sub-treeing‖ ...................................................................................................... 48

3.4 Optimização de ―sub-chunking‖ .................................................................................................. 50

4 Estudo do algoritmo Multi-Way ........................................................................................................... 52

4.1 Dados de teste ............................................................................................................................ 52

4.2 Estudo do efeito da variação na densidade dos dados .............................................................. 53

4.3 Estudo do efeito da variação do volume de dados ..................................................................... 55

Page 6: Algoritmos para a Geração de Hipercubos

5

4.3.1 Efeito da variação do número de dimensões ...................................................................... 55

4.3.2 Efeito da variação da cardinalidade das dimensões........................................................... 58

5 Balanço final ........................................................................................................................................ 63

6 Referências ......................................................................................................................................... 64

Page 7: Algoritmos para a Geração de Hipercubos

6

Lista de figuras

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

Figura 2 – Malha de cubóides para um cubo 4D [Han2001a] .................................................................... 16

Figura 3 – Exemplo de um modelo multidimensional [Chanduri1997] ....................................................... 17

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

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

Figura 6 – Pseudocódigo relativo ao algoritmo 2N ...................................................................................... 23

Figura 7 - Exemplo de uma malha de procura [Agrawal1996] ................................................................... 24

Figura 8 - Parte da malha de procura transformada [Agrawal1996]........................................................... 25

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

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

.................................................................................................................................................................... 26

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

.................................................................................................................................................................... 27

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

Figura 13 – Pseudocódigo genérico do algoritmo Multi-Way ..................................................................... 29

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

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

Figura 16 - Requisitos de memória para duas ordenações diferentes das dimensões [Zhao1997] .......... 34

Figura 17 – Representação de um cubo 3D segundo [Tam1998] .............................................................. 36

Figura 18 – Representação do cubo C com 18 chunks [Tam1998] ........................................................... 37

Figura 19 – MMST para o cubo C [Tam1998] ............................................................................................ 38

Figura 20 – MNST para o cubo C [Tam1998] ............................................................................................. 39

Figura 21 – Relação entre cubóides e subcubóides em relação à célula V(0, 0, 0) usando R-cubing

[Tam1998] ................................................................................................................................................... 40

Figura 22 – Processo de adição do chunk 0 aos chunks subcubóides relacionados [Tam1998] .............. 41

Figura 23 - Exemplo de uma H-tree [Agrawal1994] ................................................................................... 43

Figura 24 - Árvore de computação top-down [Xin2003] ............................................................................. 44

Figura 25 – Pseudocódigo correspondente à criação da MMST................................................................ 49

Figura 26 – Exemplo de uma MMST para O = (A, B, C, D)........................................................................ 50

Figura 27 - Pseudocódigo que ilustra o mecanismo de sub-chunking ...................................................... 51

Figura 28 – Efeito da variação da densidade dos dados no número de leituras e escritas efectuadas por

MW .............................................................................................................................................................. 54

Figura 29 – Efeito da variação da densidade dos dados no tempo usado por MW para calcular o cubo 54

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

algoritmo MW .............................................................................................................................................. 55

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

Page 8: Algoritmos para a Geração de Hipercubos

7

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

algoritmo MW .............................................................................................................................................. 57

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

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

Figura 35 – Efeito da variação da cardinalidade das dimensões no número de leituras efectuadas ........ 59

Figura 36 - Efeito da variação da cardinalidade das dimensões no número de escritas efectuadas ........ 59

Figura 37 – Tempo consumido no cálculo do agregado pelas diferentes implementações para 2560000

tuplos ........................................................................................................................................................... 60

Figura 38 – Efeito da variação da cardinalidade das dimensões no tempo de cálculo do cubo ................ 61

Figura 39- Comparação entre as leituras realizadas para diferentes cardinalidades de dimensões ......... 61

Figura 40 – Comparação entre as escritas realizadas para diferentes cardinalidades de dimensões ...... 62

Page 9: Algoritmos para a Geração de Hipercubos

8

Lista de tabelas

Tabela 1 – Volume de vendas em função do tempo e do tipo de item para a cidade de Vancouver

[Han2001a] .................................................................................................................................................. 14

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

Tabela 3 – Roll-up das vendas por modelo, ano e cor adaptado de [Gray1997] ....................................... 18

Tabela 4 - Roll-up das vendas por modelo, ano e cor como sugerido por Chris Date, adaptado de

[Gray1997]................................................................................................................................................... 19

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

Tabela 6 - Linhas a acrescentar à tabela 3 adaptado de [Gray1997] ........................................................ 19

Tabela 7 - Cross table para as vendas da marca Chevy adaptado de [Gray1997].................................... 20

Tabela 8 – Ordem das células do cubo no array [Tam1998] ...................................................................... 36

Tabela 9 – Exemplo de notação utilizada para identificar os agregados e seus elementos ...................... 48

Tabela 10 – Plano de testes ....................................................................................................................... 53

Page 10: Algoritmos para a Geração de Hipercubos

9

Lista de abreviaturas

BUC Bottom-Up Computation

mDC Mínimo divisor comum

MDC Máximo divisor comum

MMST Minimum Memory Spanning Tree

MNST Minimum Number Spanning Tree

MOLAP Multidimensional On-Line Analytical Processing

MW Multi-Way Array

OLAP On-Line Analytical Processing

ROLAP Relational On-Line Analytical Processing

SC Sub-Chunking

ST Sub-Treeing

SQL Structured Querying Language

Page 11: Algoritmos para a Geração de Hipercubos

10

1 Introdução

Ao longo das últimas décadas, as nossas capacidades de gerar, recolher e coleccionar dados têm

aumentado de forma significativa. A investigação crescente na área das tecnologias de informação e

sistemas de bases de dados desde a década de 70, associada ao custo cada vez menor e consequente

vulgarização dos recursos de hardware, tornou prática relativamente comum o armazenamento de

diferentes tipos de dados em estruturas relacionais. Consequentemente, a maioria das organizações

começou a manter dados sobre os seus eventos, actividades e clientes, tais como inventários, históricos

de vendas, fichas de clientes, dados sobre o mercado, entre outros. O facto de efectuar esta

armazenagem pode ser convertido numa vantagem competitiva, desde que os dados sejam analisados

criteriosamente e com rigor, por forma a extrair deles informação útil. Porém, a quantidade de dados

acumulados atingiu grandes dimensões e cresceu muito rapidamente, pelo que excedeu a capacidade

humana para os compreender e analisar. Por esta razão, as decisões não eram realmente tomadas com

base na informação oculta nas bases de dados, dando origem a uma situação designada como ―data rich

but information poor‖ [Han2001a].

Assim sendo, as exigências do mundo moderno e em constante mudança levaram à criação de várias

técnicas e ferramentas para auxiliar os indivíduos encarregues das tomadas de decisão nessa tarefa. A

partir da década de 80, a área das tecnologias de informação verificou novamente um grande

crescimento, com a adopção generalizada do modelo relacional e a intensificação da investigação na

área das bases de dados, nomeadamente a nível dos modelos de dados e de bases de dados

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

investigação nesta área passou a focar igualmente temas relacionados com a distribuição, partilha de

dados e a heterogeneidade das bases de dados. Surgiram, assim, sistemas sofisticados de apoio à

decisão que permitiram às organizações agilizar e tornar mais eficiente o processo de tomada de

decisões com base nos dados armazenados. O termo datawarehousing refere-se exactamente a um

conjunto de tecnologias de suporte à decisão que possibilitam a análise da informação oculta pela

quantidade de dados. Como as bases de dados operacionais estão organizadas no sentido de optimizar

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

suporte à decisão, as datawarehouses são preferidas em relação às bases de dados correntes pelo facto

de conterem registos históricos que agregam dados de diferentes fontes. Este tipo de repositório pode

ser implementado sobre os sistemas de gestão de base de dados relacionais, recorrendo a extensões de

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

um outro tipo de data warehouses que implementam o modelo de dados multidimensional, no qual os

dados são representados na forma de um cubo, implementados em estruturas especiais (por exemplo,

arrays).

Independentemente do tipo de implementação, um aspecto fulcral na análise de dados organizados

segundo o modelo multidimensional é a computação eficiente de agregações segundo várias dimensões

do cubo, ou seja, a computação dos vários cubóides que compõem um cubo. Os algoritmos concebidos

Page 12: Algoritmos para a Geração de Hipercubos

11

para este fim devem levar em conta a quantidade de memória que pode ser consumida na computação

dos agregados e o tempo dispendido. Apesar do interesse generalizado em torno dos sistemas de apoio

à decisão e tecnologias relacionadas, a discussão aberta sobre estes algoritmos não é uma área

privilegiada de investigação académica. A maioria das implementações destes algoritmos faz parte de

soluções de business intelligence desenvolvidas para comercialização e, como tal, não estão acessíveis.

1.1 Motivação

O uso crescente de ferramentas de apoio à decisão faz com que as questões relacionadas com as data

warehouses e o modelo multidimensional sejam importantes, na medida em que determinam o

desempenho dessas ferramentas e a qualidade dos resultados obtidos. O objectivo dos cubos é

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

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

encontrar. Existem diferentes técnicas para realizar a computação de agregados multidimensionais,

sendo cada uma delas mais adequada a determinados problemas, e não existe uma técnica universal.

Além da complexidade inerente à computação dos agregados, um dos principais problemas que se

põem a estes algoritmos é o carácter dos dados, que muitas vezes são esparsos e podem reduzir a

eficiência de um algoritmo se isso não for levado em conta. Logo, os principais desafios nesta área

consistem na implementação dos algoritmos de forma a que sejam eficientes e permitam obter

resultados no menor espaço de tempo possível. Com efeito, a implementação pode fazer toda a

diferença no desempenho deste tipo de algoritmos.

1.2 Objectivo da tese

Devido ao facto de o algoritmo Multi-Way, se apresentar como um dos mais promissores, optou-se por

aprofundar o seu estudo. Assim, o objectivo deste trabalho consiste em estudar aprofundadamente o

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

identificar as suas limitações face a bases de dados com características variadas. Na sequência desse

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

maior número de situações. Esta tese formaliza a proposta dessas optimizações e relata os resultados

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

1.3 Estrutura da tese

A tese encontra-se organizada da seguinte forma: a secção 2 descreve a investigação realizada no

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

secção 3 apresenta o trabalho realizado, definindo o problema que se pretende estudar no contexto dos

trabalhos prévios na área e descrevendo a implementação e as optimizações propostas ao algoritmo

Page 13: Algoritmos para a Geração de Hipercubos

12

Multi-Way; a secção 4 apresenta os resultados dos testes realizados para aferir o desempenho do

algoritmo numa variedade de dados e em simultâneo avaliar o real impacto das optimizações propostas;

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

Page 14: Algoritmos para a Geração de Hipercubos

13

2 Trabalhos prévios sobre geração de hipercubos

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

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

vários algoritmos que foram concebidos para ultrapassar estes problemas.

2.1 Modelo de dados multidimensional

Com a crescente quantidade de dados disponíveis, o recurso a data warehouses torna-se cada vez mais

necessário e frequente. Apesar disso, o conceito de data warehouse não tem uma definição única.

Normalmente, o termo é utilizado para referir uma base de dados que é mantida separada da base de

dados operacional de uma organização e que está integrada com vários sistemas que permitem efectuar

o processamento e análise dos dados. Uma das definições mais usadas defende que a data warehouse

é um conjunto de dados organizados em torno de um determinado tópico, resultante da integração de

diferentes fontes de dados, mantidos de forma persistente e que expressa uma perspectiva histórica

desses dados. Segundo Inmon, o conceito de data warehouse pode ser definido como um conjunto

integrado e não-volátil de informação orientada a um determinado tema e que expressa a variação

desses dados ao longo do tempo, podendo esses dados ser usados para fins de apoio a decisões

[Inmon1996].

Esta separação entre a base de dados operacional e a data warehouse promove a eficiência e

desempenho de cada um dos sistemas, tendo em conta os diferentes fins a que se destina. A principal

função das bases de dados operacionais é a realização de transacções online e processamento de

interrogações (queries), sendo esse conjunto de operações conhecido como processamento de

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

objectivo servir de suporte à análise de dados e tomada de decisões, pelo que sobre elas são realizados

outros tipos de operações. Normalmente, tratam-se de operações que manipulam grandes quantidades

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

diferentes níveis de granularidade. A este tipo de operações dá-se o nome de processamento analítco

online (online analytical processing - OLAP).

De uma forma genérica, uma data warehouse é composta por uma tabela de factos, onde se encontram

os dados que podem ser objecto de análise, e tabelas de dimensões, que armazenam os dados sobre as

perspectivas segundo as quais os factos podem ser analisados. Tanto as data warehouses como as

operações OLAP são baseadas no modelo multidimensional, em que os dados são visualizados sob a

forma de um cubo. Um cubo é definido por um conjunto de dimensões e de factos. De uma forma

genérica, as dimensões são as perspectivas ou entidades em relação às quais os factos se referem.

Por exemplo, uma empresa pode manter uma data warehouse de vendas como forma de manter

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

data de venda. Cada dimensão pode estar associada a uma tabela que pormenoriza a sua descrição. No

Page 15: Algoritmos para a Geração de Hipercubos

14

exemplo anterior, a tabela de dimensão para os itens vendidos pode conter os atributos nome, categoria

e marca. Quanto aos factos, estes são medidas numéricas correspondentes ao principal objectivo da

data warehouse. Ainda no exemplo anterior, o número de unidades vendidas ou o volume total de

vendas em dinheiro são factos possíveis para uma data warehouse de vendas.

Ao contrário do sólido geométrico com o nome correspondente, em OLAP os cubos não são

necessariamente tridimensionais mas sim n-dimensionais. A melhor forma de esclarecer este conceito

passa por exemplificar o mesmo. Para tal, considere-se a tabela abaixo, que representa informação

sobre as vendas de uma determinada organização apresentada em função do tempo (Tempo) e do tipo

de item vendido (Item).

Tabela 1 – Volume de vendas em função do tempo e do tipo de item para a cidade de Vancouver [Han2001a]

Tempo

(trimestre)

Vendas para todas as localizações em Vancouver

Item (tipo)

Entretenimento Computador Telefone Segurança

Q1 605k 825k 14k 400k

Q2 680k 952k 31k 512k

Q3 812k 1023k 30k 501k

Q4 927k 1038k 38k 580k

No caso de pretendermos visualizar a informação relativa às vendas não apenas em função do tempo e

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

acrescentar à tabela acima uma terceira dimensão, obtendo-se assim uma série de tabelas diferentes1.

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

Tempo

(trimestre)

Localização = Vancouver

Item

Entretenimento Computador Telefone Segurança

Q1 605k 825k 14k 400k

Q2 680k 952k 31k 512k

Q3 812k 1023k 30k 501k

Q4 927k 1038k 38k 580k

Tempo

(trimestre)

Localização = Montréal

Item

Entretenimento Computador Telefone Segurança

Q1 818k 746k 43k 591k

Q2 894k 769k 52k 682k

Q3 940k 795k 58k 728k

Q4 978k 864k 59k 784k

1 Estas tabelas podem ser representadas numa só pivot tabela, tal como se descreve mais adiante.

Page 16: Algoritmos para a Geração de Hipercubos

15

Tempo

(trimestre)

Localização = New York

Item

Entretenimento Computador Telefone Segurança

Q1 1087k 968k 38k 872k

Q2 1130k 1024k 41k 925k

Q3 1034k 1048k 45k 1002k

Q4 1142k 1091k 54k 984k

Tempo

(trimestre)

Localização = Chicago

Item

Entretenimento Computador Telefone Segurança

Q1 854k 882k 89k 623k

Q2 943k 890k 64k 698k

Q3 1032k 924k 59k 789k

Q4 1129k 992k 63k 870k

As tabelas acima equivalem conceptualmente ao cubo 3D da figura abaixo.

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

Supondo que se pretendesse adicionar outra dimensão, designada como Fornecedor, à informação da

tabela 1, obter-se-ia um cubo 4D, o que não é trivial de representar ou visualizar. Porém, podemos

considerar um cubo 4D como uma série de cubos 3D para cada uma das combinações possíveis das

quatro dimensões três a três. Desta forma, qualquer informação n-dimensional pode ser representada

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

para representar o carácter multidimensional dos dados.

Page 17: Algoritmos para a Geração de Hipercubos

16

Dado um conjunto de dimensões, é possível construir uma malha de cubóides em que cada um deles

mostra os dados em diferentes níveis de sumarização ou agregação, isto, agrupados segundo diferentes

subconjuntos das dimensões. Um cubo como o da figura 1 é normalmente designado de cubóide base,

enquanto o cubóide 0D, que apresenta o mais alto grau de sumarização possível, é o cubo ápice. Ao

conjunto da malha de cubóides dá-se o nome de cubo de dados (data cube).

Figura 2 – Malha de cubóides para um cubo 4D [Han2001a]

O modelo multidimensional de dados pode ser implementado segundo um esquema em estrela, em floco

de neve ou em constelação de factos. O esquema em estrela é o esquema mais usado para representar

data warehouses, sendo composto por uma tabela central de factos e várias tabelas de dimensão

ligadas à tabela central. O esquema em floco de neve é uma variante do esquema em estrela que, ao

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

devidos ao facto de cada dimensão corresponder a uma única tabela no esquema em estrela. A nível

arquitectural, as data warehouses podem ser implementadas sobre sistemas de gestão de bases de

dados relacionais, designados como servidores relacionais (servidores ROLAP) e que suportam métodos

especiais que lhes permitem implementar o modelo multidimensional e as operações sobre ele. Outra

arquitectura possível para as data warehouses assenta em servidores multidimensionais (servidores

MOLAP), que recorrem a estruturas de dados apropriadas para implementar o modelo multidimensional

e as operações necessárias.

Para tirar partido da flexibilidade proporcionada pelo modelo multidimensional, existem várias operações

que podem ser realizadas sobre o cubo e permitem obter diferentes vistas dos dados. Para a descrição

das operações mais comuns, considere-se o modelo multidimensional representado na figura 3.

Page 18: Algoritmos para a Geração de Hipercubos

17

Figura 3 – Exemplo de um modelo multidimensional [Chanduri1997]

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

dimensão Cidade definida na figura 3, um exemplo de uma operação de roll-up será aquela que agrega

os dados subindo na hierarquia do nível cidade para o nível país. Este tipo de operação pode também

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

dados em torno das dimensões que não são removidas.

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

detalhe para um nível de maior detalhe.Tomando a dimensão Produto na figura 3, um exemplo de uma

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

semelhança do que se verifica para a operação de roll-up, a operação de drill-down pode ser conseguida

adicionando dimensões ao cubo, no sentido do maior detalhe permitido pela operação.

As operações de slice e dice correspondem a acções de selecção por parte do utilizador. Enquanto a

primeira corresponde à selecção de dados do cubo tendo em conta apenas uma dimensão, a segunda

corresponde à selecção de dados por mais que uma dimensão. O resultado de qualquer uma das

operações é o subcubo correspondente aos critérios enumerados. No exemplo dado na figura 3, é

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

referentes à dimensão cidade e ao dia de venda de um determinado produto.

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

possibilitar outra perspectiva dos dados. O significado desta operação é melhor entendido se se

visualizar o modelo multidimensional da figura 3 representado numa folha de cálculo em que cada linha

corresponde a uma venda, representando cada coluna uma dimensão e a última coluna o valor da venda

[Chanduri1997]. O valor contido em cada célula representa o valor agregado de uma determinada

medida (neste caso, o valor de vendas) quando a primeira dimensão tem o valor x e a segunda

dimensão tem o valor y. Seguindo o exemplo da figura 3 e assumindo que consideramos apenas as

dimensões cidade e ano, então o eixo x representa todos os valores possíveis de cidade e o eixo y

representa todos os valores possíveis de ano. Consequentemente, o ponto (x, y) representa o valor

agregado de vendas para a cidade x no ano y. A operação de pivoting permite trocar os eixos x e y, o

Page 19: Algoritmos para a Geração de Hipercubos

18

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

cidade y.

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

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

2.2 O operador DATA CUBE

Os utilizadores típicos de sistemas de apoio à decisão estão mais interessados em extrair informação

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

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

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

a concepção do operador DATA CUBE, destacando-se desses problemas o cálculo de totais para

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

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

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

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

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

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

um subtotal.

Tabela 3 – Roll-up das vendas por modelo, ano e cor adaptado de [Gray1997]

Marca Ano Cor

Vendas

por modelo

por ano por cor

Vendas

por modelo

por ano

Vendas

por

modelo

Chevy 1994 Preto 50

Branco 40

90

1995 Preto 85

Branco 115

200

290

Porém, a representação desta tabela não é relacional visto que existem células vazias, inviabilizando

assim a hipótese de funcionarem como identificadores unívocos (chaves). Para obviar este problema,

Chris Date recomendou a criação de 2n colunas de agregação para um roll-up de n elementos

[Gray1997], obtendo-se assim a tabela 4.

Page 20: Algoritmos para a Geração de Hipercubos

19

Tabela 4 - Roll-up das vendas por modelo, ano e cor como sugerido por Chris Date, adaptado de [Gray1997]

Modelo Ano Cor Unidades

Chevy 1994 Preto 50

Chevy 1994 Branco 40

Chevy 1994 ALL 90

Chevy 1995 Preto 85

Chevy 1995 Branco 115

Chevy 1995 ALL 200

Chevy ALL ALL 290

Esta alternativa, apesar de elegante, aumenta significativamente o número de células a calcular quando

o número de dimensões aumenta ligeiramente. Para evitar o crescimento exagerado das tabelas devido

à adição das novas colunas, os autores propuseram a redefinição dos valores das colunas, introduzindo

o valor ALL. Cada valor ALL representa um conjunto de dados sobre o qual já foi computado o valor da

agregação. A tabela 5 mostra o resultado da aplicação desta representação.

Tabela 5 - Resultado após computada a agregação, adaptado de [Gray1997]

Marca Ano Cor Vendas Vendas

Por modelo

Por ano

Vendas

Por

modelo

Chevy 1994 Preto 50 90 290

Chevy 1994 Branco 40 90 290

Chevy 1995 Preto 85 200 290

Chevy 1995 Branco 115 200 290

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

efectuando tantas uniões quantas as dimensões a serem consideradas. Porém, como a operação de roll-

up é simétrica, a tabela anterior necessita de ser acrescentada com a tabela 6 para que passe a

representar um cubo.

Tabela 6 - Linhas a acrescentar à tabela 3 adaptado de [Gray1997]

Modelo Ano Cor Unidades

Chevy ALL Preto 135

Chevy ALL Branco 135

As linhas constantes da tabela 6 podem ser obtidas adicionando uma união à instrução de SQL a partir

da qual se obteve a tabela 5. O resultado desta junção permite que a operação de roll-up seja simétrica e

gera a tabela 7, a que se dá o nome de cross tab.

Page 21: Algoritmos para a Geração de Hipercubos

20

Tabela 7 - Cross table para as vendas da marca Chevy adaptado de [Gray1997]

Chevy 1994 1995 Total (ALL)

Chevy ALL Preto 135

Chevy ALL Branco 155

Total (ALL) 90 200 290

Esta pequena demonstração é suficiente para mostrar que, apesar do uso de group-by e union resolver o

problema de calcular os agregados, a forma como isso é conseguido não é eficiente em termos de

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

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

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

realmente um objecto relacional [Gray1997].

Em 1996, Gray et al propuseram o operador DATA CUBE ou, mais simplemente, CUBE, capaz de

computar agregados sobre todas as combinações possíveis de atributos para um conjunto de

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

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

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

Page 22: Algoritmos para a Geração de Hipercubos

21

O cubo 0D (em cima à esquerda na figura 4) refere-se ao agregado vazio e corresponde à soma total de

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

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

de todos esses valores; na figura 2, corresponde ao agregado segundo o atributo cor. Por sua vez, o

cubo 2D (em cima à direita na figura 4) corresponde a um plano, duas linhas e um ponto, ou seja, a uma

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

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

equivale à intersecção de três cross tables, correspondendo cada uma delas à agregação por diferentes

grupos de atributos.

Este novo operador surgiu como forma de ultrapassar as limitações demonstradas pelo uso de SQL. O

trabalho apresentado foi posteriormente considerado tão relevante que foi mesmo realizada uma

implementação desse operador, com algumas alterações, em SQL, tal como referido em [Zhao1997].

2.3 Selecção de agregados para pré-computação

Tipicamente, os sistemas de apoio à decisão devem ser capazes de lidar com interrogações complexas

sobre bases de dados de grande dimensão e devolver respostas em tempos curtos, o que faz com que a

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

normalmente são vistos sob a forma do modelo multidimensional, uma das técnicas mais usadas neste

sentido é a pré-computação de alguns agregados por forma a evitar a repetição deste cálculo. Este

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

plataforma para escolher quais os agregados que devem ser calculados previamente [Harinarayan1996].

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

cada célula é representada por uma lista de valores relativos a cada uma das dimensões que a

compõem, qualquer célula que tenha o valor ALL como um dos seus componentes depende de outra

célula. Qualquer célula cuja composição não inclua o valor ALL pode ser obtida a partir da tabela de

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

fornecedor (S) e cliente (C). Assim sendo, existem 23 conjugações possíveis desses atributos: (peça,

fornecedor, cliente), (peça, cliente), (peça, fornecedor), (fornecedor, cliente), (peça), (fornecedor),

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

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

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

atributos.

Page 23: Algoritmos para a Geração de Hipercubos

22

Figura 5 - Malha de combinações possíveis para 3 atributos [Harinarayan1996]

Considerando duas interrogações Q1 e Q2, diz-se que Q1 depende de Q2 se Q1 pode ser respondida

usando apenas os resultados de Q2. Tomando a figura 5, a interrogação (peça) pode ser respondida

usando os resultados da interrogação (peça, cliente); logo, a interrogação (peça) depende da

interrogação (peça, cliente).

Este trabalho introduziu também o modelo de custo linear (linear cost model) para exprimir o custo de

uma determinada interrogação. Segundo este modelo, o tempo necessário para responder a uma

interrogação Q corresponde ao número de linhas existentes na tabela de dados e que são necessárias

para responder à interrogação QA, previamente respondida e da qual a interrogação Q depende.

2.4 Computação de agregados multidimensionais

Tal como foi referido, a tarefa de computar um cubo corresponde, basicamente, a pré-computar e

armazenar agregações de dados multidimensionais de maneira a que seja possível analisar

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

de tempo e espaço. Logo, o desempenho é uma questão fulcral no que se refere à computação e

representação do cubo, tendo sido desenvolvidos vários algoritmos para esta tarefa.

Segundo [Gray1997], as funções de agregação podem ser classificados em três categorias:

Funções distributivas – a função F( ) é considerada distributiva se existir uma função G( ) tal que

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

MIN( ), MAX( ) e SUM( ).

Funções algébricas – a função F( ) é considerada algébrica se existir um tuplo de ordem M de

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

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

Funções holísticas – uma função F( ) é considerada holística se não existir uma constante M tal

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

No que se refere às funções holísticas, a forma mais eficiente de computar agregados deste tipo de

funções é o recurso ao algoritmo 2N

[Gray1997]. Este algoritmo começa por reservar um apontador

Page 24: Algoritmos para a Geração de Hipercubos

23

(handle) para cada célula do cubo e, sempre que é recebido um novo tuplo (x1, x2, ..., xN, v) em que xi

representa as coordenadas dessa célula e v o valor nela contido, a função de agregação é invocada 2N

vezes, ou seja, uma vez para cada apontador de cada célula do cubo cujo valor equivale a v. A

designação 2N advém do facto de cada coordenada poder ser xi ou ALL. Quando todos os tuplos tiverem

sido computados, a função final é invocada para cada um dos (𝐶𝑖 + 1) nós do cubo, em que Ci

corresponde à cardinalidade da dimensão i.

tuplo (X1,X2,…,Xn,val)

h apontador para o tuplo

hl lista de apontadores

agg função de agregação

2N-algoritmo(tuplo)

para cada tuplo

fazer

para cada Xi no tuplo

Xi ALL

agg(h,val)

novoTuplo tuplo com posição Xi removida

2N-algoritmo(novoTuplo)

até que

tuplo=(val)

Figura 6 – Pseudocódigo relativo ao algoritmo 2N

Os cubos de funções distributivas são relativamente fáceis de computar na medida em que a natureza

da própria função de agregação permite que, sendo o núcleo representado como um array

n-dimensional em memória e que cada dimensão tenha cardinalidade Ci +1, os agregados

n-1-dimensionais possam ser calculados projectando cada uma das dimensão. Os cubos de funções

algébricas são mais difíceis de computar que os cubos das funções distributivas pois este tipo de

funções pressupõem o cálculo de valores intermédios para poderem apresentar o resultado final.

Se o cubo não puder ser mantido em memória devido à sua dimensão, não pode ser representado por

meio de arrays e devem ser usadas técnicas que permitam fazer a sua partição, tais como ordenamento

ou recurso a funções de dispersão. No caso de o cubo ser esparso, apenas os elementos não-nulos e os

super-agregados devem ser representados, o que deve ser conseguido através de dispersão ou

estratégias de indexação para os valores dos agregados.

Em seguida descrevem-se as três abordagens principais à computação de agragados multidimensionais,

que estão na base da geração eficiente de cubos: os algoritmos baseados em ordenação e dispersão

(sorting e hashing), os algoritmos baseados em partições e os algoritmos baseados em arrays.

2.4.1 Algoritmos baseados em ordenação e dispersão (sorting e hashing)

O trabalho de [Agrawal1996] foi dos primeiros publicados sobre a questão da optimização do processo

de computação de agregados, tendo destacado a necessidade de generalizar os operadores de

agregação para poderem ser aplicados à computação de cubos armazenados em tabelas relacionais.

Page 25: Algoritmos para a Geração de Hipercubos

24

Para isso, foram estudados dois métodos básicos para computação de um único agregado: um deles é

baseado em ordenamento (PipeSort) e outro é baseado em dispersão (PipeHash) [Agrawal1996]. Estes

métodos podem ser aplicados à computação de múltiplos agregados recorrendo às seguintes

optimizações:

Pais mais pequenos (smallest-parents) – consiste em computar um agregado a partir de outros

de menor dimensão já computados.

Resultados em cache (cache-results) – consiste em manter em memória os resultados de um

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

entrada e saída.

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

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

Partilha da ordenação (share-sorts) – apenas se aplica a algoritmos baseados em ordenação e

aposta na partilha dos custos associados à ordenação por vários agregados.

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

refere-se à partição da tabela de dispersão, caso seja demasiado grande para os recursos de

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

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

cada fio de computação constituído por agregados que podem ser computados pelo mesmo varrimento

dos dados de entrada. De forma a estabelecer quais os agregados que podem ser computados a partir

de outros e qual a sequência pela qual os atributos devem ser tratados, foi utilizado o conceito de malha

de procura apresentado em [Harinarayan1996].

Basicamente, uma malha de procura é um grafo em que cada nó representa um agregado do cubo.

Quando um nó i está ligado a um nó j, isso significa que o agregado j pode ser gerado a partir do

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

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

agregados que contêm exactamente k atributos.

Figura 7 - Exemplo de uma malha de procura [Agrawal1996]

Page 26: Algoritmos para a Geração de Hipercubos

25

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

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

ALL. Cada arco da malha está etiquetado com dois custos: o custo S(eij) corresponde ao custo de

computar j a partir de i quando i ainda não está ordenado, enquanto o custo A(eij) corresponde ao custo

de computar j a partir de i quando i já está ordenado [Agrawal1996].

2.4.1.1 PipeSort

O algoritmo PipeSort parte da malha de procura com os respectivos custos associados e assume que se

conhece uma estimativa do número de valores distintos associados a cada agregado. A malha é

percorrida desde o nível k = 0 até ao nível k = N - 1, sendo N o número total de atributos, com o objectivo

de determinar a melhor forma de computar o nível k a partir do nível k + 1. Para isso, é acrescentado ao

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

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

considerando que se trabalha sobre o nível 1 da malha apresentada na figura 7. As setas em traço cheio

representam os arcos A( ), enquanto as setas a tracejado representam os arcos S( ), sendo o custo de

todos os arcos que saem de um nó indicados sob eles.

Figura 8 - Parte da malha de procura transformada [Agrawal1996]

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

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

partir do qual h pode ser calculado. Como se pode ver na figura 20, o nó A fica ligado ao nó AB por um

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

ordem BA para que B possa ser obtido a partir dele sem necessidade de reordenação e A seja obtido

reordenando BA. Da mesma forma, como o nó C está ligado ao nó AC por um arco A( ), o nó AC será

computado pela ordem CA. Quanto ao nó BC, como não está ligado a nenhum agregado de nível 1, é

indiferente a ordem pela qual é calculado.

Figura 9 - Resultado obtido pelo algoritmo PipeSort para k = 1 [Agrawal1996]

Page 27: Algoritmos para a Geração de Hipercubos

26

Seguidamente, é feita uma ordenação com base no sub-grafo gerado e é obtido um conjunto de

sequências de agregados a serem computadas em sequência (pipeline).

Este algoritmo concilia as optimizações partilha da ordenação (share-sort), uma vez que os dados são

ordenados numa determinada ordem que permita computar todos os agregados que partilham um

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

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

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

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

2.4.1.2 PipeHash

O algoritmo PipeSort trabalha igualmente sobre a malha de procura e começa por escolher, para cada

agregado, o seu predecessor de menor dimensão, obtendo assim a árvore de custo mínimo. Porém, os

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

dessa árvore, pelo que é necessário decidir quais serão computados em conjunto, quando reservar

memória para diferentes tabelas de dispersão e que atributos serão usados para dividir os dados

[Agrawal1996].

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

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

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

abaixo apresenta a árvore de cobertura mínima para a malha de procura apresentada na figura 7.

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

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

árvore, pelo que é necessário dividir a árvore assim obtida. A árvore é dividida de tal forma que cada

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

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

Page 28: Algoritmos para a Geração de Hipercubos

27

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

sub-árvore possível a partir da árvore de custo mínimo.

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

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

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

22. Para computar esta árvore, calcula-se primeiro o agregado ABCD e a partir deste ABC, ABD e ACD;

ABCD e ABD são guardados em disco, calcula-se AD a partir de ACD e ACD e AD são guardados em

disco; ABC é lido para a partir dele se calcular AB e AC, sendo ABC e AC guardados em disco; por fim,

AB é lido para calcular A e AB e A são guardados em disco. Depois desta sub-árvore ter sido calculada,

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

11.

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

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

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

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

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

fez a partição.

2.4.2 Algoritmos baseados em partição

Os dados provenientes do mundo real são frequentemente de natureza esparsa, o que justifica o estudo

e desenvolvimento de técnicas orientadas para esse tipo de dados. Nestas condições, a representação

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

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

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

que possam ser armazenados em memória e efectuar a operação sobre cada um desses fragmentos

independentemente. Existem dois algoritmos para computação de cubos a partir de dados esparsos:

Page 29: Algoritmos para a Geração de Hipercubos

28

Partitioned-Cube e Memory-Cube [Ross1997]. O algoritmo Memory-Cube foi concebido para computar

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

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

as partições assim obtidas.

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

fixando cada um dos valores possíveis para um atributo e calculando os tuplos desse sub-cubo. Em

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

em vez de voltar a ler os dados para calcular o cubo ALL, apenas é necessário ler o cubóide de

granularidade mais fina, que pode ser bastante menor que a relação que representa e nunca é maior que

essa relação [Ross1997]. O algoritmo divide o cubo em n + 1 subcubos mais pequenos, o que faz com

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

Considerando uma relação que possui quatro atributos ordenados como (A, B, C, D), o algoritmo

procede à partição dos dados tomando os atributos por essa ordem e calcula os cubóides respectivos

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

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

cubóides que contêm A como atributo. Seguidamente, a relação é dividida pelo atributo B, sendo

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

tuplos dos cubóides que contêm B. A partição continua enquanto não se verificar que os cubóides

restantes podem ser calculados em memória, embora o algoritmo não especifique exactamente como

realizar a divisão. A figura 12 mostra a ordem pela qual o algoritmo calcula os vários cubóides sempre

que o resultado da partição cabe em memória.

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

O algoritmo Memory-Cube foi desenvolvido para o caso em que toda a relação em estudo pode ser

mantida em memória. Apesar de ser um bloco constituinte do algoritmo Partitioned-Cube, pode funcionar

de forma independente uma vez que é capaz de computar um cubo por completo sem necessidade de

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

capacidade de armazenamento extra além da que é utilizada pela relação. Basicamente, usa o conceito

Page 30: Algoritmos para a Geração de Hipercubos

29

de malha de procura proposto pelo algoritmo PipeSort, a partir da qual determina quais os cubóides que

podem ser obtidos a partir de outros no sentido de minimizar o número de caminhos que é necessário

percorrer para cobrir todos os nós. Assim, para cada cubo o algoritmo toma um caminho e ordena a

relação em memória tendo em conta a ordenação dos atributos no nó inicial. Seguidamente, os dados

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

granularidade.

Os resultados mostram que o algoritmo faz o número mínimo possível de ordenações e consegue tirar

partido dos prefixos comuns de diferentes agregados de forma a optimizar o custo a nível de

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

saída dos resultados, o que faz com que a carga total deste tipo de operações seja linear em relação ao

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

2.4.3 Algoritmos baseados em arrays

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

tipo ordenação e dispersão não sejam aplicáveis. O próprio facto de ser utilizado outro tipo de estrutura

de dados faz com que seja necessário ter em conta uma série de factores relacionados com o

carregamento e armazenamento eficientes de arrays de grandes dimensões e muito esparsos.

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

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

repetir a operação para calcular cada um dos sub-agregados. Por questões de desempenho, os arrays

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

designada de chunking [Zhao1997].

DS fonte de dados

c chunk

chunkSize tamanho do chunk

O {D1,D2,...,Dn : |D1|≤|D2|≤...≤|Dn|}

T MMST para ordem O

m número de elementos de O

para cada c no nivel m do array

carregar dados para c a partir de DS

i n

para cada Di

para cada posição de c

val valor da posição

fazer

nextLevel m-1

para cada nó em nextLevel

remover posição não utilizada em nó

agregar valor no nó

até

nextLevel≥0

i i-1

Figura 13 – Pseudocódigo genérico do algoritmo Multi-Way

Page 31: Algoritmos para a Geração de Hipercubos

30

A técnica tradicional de armazenar o array em função de uma coluna ou de uma linha pode não ser

eficiente em muitas situações. Considere-se uma representação de um array bidimensional com as

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

nas colunas. Aceder ao array em ordem a Lojas é eficiente, na medida em que cada página em disco

contém várias Lojas. Porém, aceder ao array em ordem a Data é ineficiente, especialmente se a

dimensão Loja for grande; nesse caso, cada página em disco só vai conter os dados relativos a uma

Data, sendo necessário carregar outra página para aceder a dados para a Data seguinte. Esta

organização cria uma assimetria entre as dimensões, favorecendo uma em detrimento de outras

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

dimensões. Entende-se por chunking uma forma de dividir arrays n-dimensionais em vários arrays n-

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

[Zhao1997].

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

estejam vazias, o que significa que não existem dados para essa combinação de coordenadas. Um

chunk é considerado denso quando mais de 40% das células contêm um valor válido [Zhao1997].

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

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

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

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

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

cubo, enquanto a eficiência a nível de computação dos agregados é assegurada pelo uso da ordem

correcta no seu cálculo. Para isso, o algoritmo apresenta os conceitos de ordenamento óptimo das

dimensões (optimal dimension order) e árvore de cobertura mínima de memória (minimum memory

spanning tree).

Apesar de ser um algoritmo característico de aplicações do tipo MOLAP, pode ser usado por sistemas do

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

computar o resultado sobre esse array e transferir os resultados obtidos para as tabelas adequadas.

Esta adaptação justifica-se pelo elevado desempenho que este algoritmo apresenta e pela boa gestão

de memória que efectua, sendo ainda mais eficiente que os algoritmos desenhados para sistemas

ROLAP.

2.4.3.1 Computação de agregados

Para compreender a mecânica do algoritmo, comecemos por computar um agregado a partir de um array

simples sem recorrer a chunking, assumindo que se dispõe de um array tridimensional com dimensões

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

corresponde a percorrer um plano através da dimensão C e realizar a agregação até que todo o array

Page 32: Algoritmos para a Geração de Hipercubos

31

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

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

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

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

de tal forma que a face AB do array está de frente para o leitor, o chunk pode ter início na parte superior

esquerda do array e percorrer um plano de dimensão ACBC, agregando todos os valores de C no

processo. Depois de percorrido este chunk na porção superior esquerda, o varrimento deste plano

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

apenas quando o plano foi todo percorrido dentro do array. Neste ponto, a porção do agregado AB

correspondente ao subplano superior esquerdo de dimensão ACBC já foi computada, pelo que este plano

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

correspondente a outro chunk. Desta forma, cada chunk apenas é lido uma vez e no fim de serem

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

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

à medida que os chunks são varridos [Zhao1997].

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

com as dimensões ABC, considere-se agora que é necessário computar AB, BC, AC, A, B, C e o

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

inicial ABC. Porém, é muito mais eficiente calcular A a partir de AB do que calcular A a partir de ABC. Se

se vir a computação do cubo como uma árvore em que ABC é a raiz, AB, BC e AC descendem de ABC,

A e C descendem de AC e assim sucessivamente. Como as dimensões do array e o tamanho de cada

um dos chunks são conhecidos, é possível determinar exactamente o tamanho do array correspondente

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

definir a árvore mínima de cobertura (minimum spanning tree) em que o predecessor de cada nó n é o

nó n’ de menor tamanho a partir do qual n pode ser computado. O funcionamento do algoritmo apoia-se

na construção da árvore mínima de cobertura para os agregados do cubo que se pretende computar.

Cada agregado Di1, Di2, ..., Dik+1 é calculado a partir do predecessor Di1, Di2, ..., Dik+1 com tamanho

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

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

libertada para o chunk seguinte de Di1, Di2, ..., Dik [Zhao1997].

O recurso ao chunking assegura a eficiência a nível de carregamento e armazenamento dos valores das

células do cubo, enquanto a eficiência a nível de desempenho é assegurada pelo uso da ordem correcta

no cálculo dos agregados. A ordem das dimensões num chunk pode ser representada como O = (Dj1, Dj2,

... , Djn), assumindo que existem n dimensões D1, D2, ..., Dn. Diferentes ordenamentos de dimensões

implicam diferentes ordens de leitura dos chunks e determinam a quantidade de memória que é

necessária para efectuar a computação. Para mostrar a importância da ordem pela qual são tomadas as

dimensões, considere-se um array de dados 3D com três dimensões (A, B e C), dividido em 64 chunks

Page 33: Algoritmos para a Geração de Hipercubos

32

como mostra a figura 9. Assume-se que a cardinalidade de cada uma das dimensões A, B e C é,

respectivamente, 40, 400 e 4000.

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

Os chunks são lidos segundo a ordem ABC, do chunk 1 para o chunk 64. Assumindo que o chunk 1 já

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

segundo a dimensão i para obter um chunk de AC e segundo a dimensão A para obter um chunk de BC.

Assim, o primeiro chunk de AB é agregado para o chunk a0b0 de AB, o primeiro chunk de AC é agregado

para o chunk a0c0 de AC e o primeiro chunk de BC é agregado para o chunk b0c0 de BC. À medida que

novos chunks são lidos, os chunks obtidos vão sendo agrupados aos chunks dos agregados

correspondentes. Note-se que os chunks foram lidos segundo a ordem (A, B, C), que corresponde a uma

ordem linear desde o chunk 1 ao chunk 64. Isso significa que b0c0 está completamente agregado depois

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

chunk b1c0. Este, por sua vez, está completamente agregado depois de terem sido lidos os chunks 5 a 8,

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

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

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

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

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

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

calcular BC é necessário memória para 1 chunk de BC, para calcular AC é necessária memória para 4

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

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

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

de uma dimensão X, |Xc| o tamanho do chunk de uma dimensão X e u o tamanho de cada elemento do

chunk [Zhao1997]. Como o tamanho de um chunk de uma dimensão é menor que o tamanho dessa

dimensão na maioria dos casos, conclui-se que é possível calcular o cubo alocando uma quantidade de

Page 34: Algoritmos para a Geração de Hipercubos

33

memória inferior à que seria ocupada pelo agregado e assim conseguir calcular mais agregados

simultaneamente. Verifica-se assim que a ordem pela qual se tomam as dimensões é determinante para

as necessidades de memória, sendo definida como ordenação óptima das dimensões (optimal dimension

order) aquela em que a computação de todos os agregados do cubo requer a quantidade possível de

memória. Formalmente, a ordem óptima das dimensões é O = (D1, D2, ..., Dn) em que |D1| ≤ |D2| ≤ ... ≤

|Dn|, sendo |Di| o tamanho da dimensão Di.

Por forma a coordenar a computação simultânea de vários agregados é utilizada a árvore de cobertura

mínima em termos da memória que é necessária. Dá-se o nome de árvore de cobertura mínima de

memória (minimum memory spanning tree – MMST) à árvore de cobertura mínima para um cubo (D1, D2,

..., Dn) construída segundo a ordem de dimensões O = (Dj1, Dj2, ..., Djn), sendo j o nível na MMST. Trata-

se de uma árvore com n+1 níveis, com (Dj1, Dj2, ..., Djn) no nível n, e em que qualquer nó num nível i

inferior ao nível n pode ser computado a partir dos nós no nível acima que contêm todas as dimensões

que compõem esse nó. Tal como o próprio nome indica, a MMST é mínima em termos da quantidade

total de memória necessária para um determinada ordem de dimensões. A figura abaixo mostra a MMST

para o array ABC segundo a ordem (A, B, C), em que os números sob cada nó indicam o número de

elementos de array necessários para esse nó.

Figura 15 - MMST para O = (A, B, C) [Zhao1997]

Estes cálculos de memória para agregados de arrays n-dimensionais foram formalizados por Zhao et al

sob a forma de uma regra. Segundo a regra, para calcular o agregado (Dj1, Dj2, ..., Djn) do array (D1, D2,

..., Dn) lido na ordem O = (D1, D2, ..., Dn) e que contém um prefixo de (D1, D2, ..., Dn) de comprimento p (0

≤ p ≤ n – 1), é necessário alocar

|𝐷𝑖|

𝑝

𝑖=1

∗ |𝐶𝑖|

𝑛−1

𝑖=𝑝+1

unidades do array, sendo |Di| o tamanho da dimensão i e |Ci| o tamanho do chunk para a dimensão i

[Zhao1997].

Page 35: Algoritmos para a Geração de Hipercubos

34

Diferentes ordenações de dimensões (D1, D2, ..., Dn) podem gerar diferentes MMSTs com diferentes

requisitos a nível de memória. Para exemplificar isto, considere-se um array com quatro dimensões

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

seguinte mostra as MMSTs geradas para a ordenação de dimensões (A, B, C, D) e (D, B, C, A),

respectivamente. Verifica-se que a MMST para a ordenação (D, B, C, A) requer aproximadamente 4 Gb

de memória, enquanto a MMST para a ordenação (A, B, C, D) requer apenas 4 Mb de memória. A

disparidade entre os requisitos de memória deve-se unicamente ao facto da troca entre A e D na

sequência das dimensões.

Figura 16 - Requisitos de memória para duas ordenações diferentes das dimensões [Zhao1997]

Se a quantidade de memória disponível for inferior à memória mínima indicada como necessária pela

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

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

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

incompletas, ou seja, aquelas para as quais não existe espaço suficiente em memória. Para decidir por

que ordem deve ser atribuída memória a cada uma das sub-árvores, os autores propõem que se utilize

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

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

2.4.3.2 Variante do algoritmo Multi-Way no sistema DBMiner

Devido ao seu bom desempenho, este algoritmo foi integrado no sistema DBMiner [Tam1998]. A ideia

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

mostram que normalmente as tarefas de exploração de dados são realizadas sobre extensos conjuntos

Page 36: Algoritmos para a Geração de Hipercubos

35

de dados, frequentemente mantidos para outros fins, e que na maioria dos casos os utilizadores não

conseguem estabelecer um objectivo definido. Isto leva a que as interrogações colocadas impliquem a

agregação de grandes quantidades de dados, o que impossibilita a rapidez desejada na resposta. O

objectivo do sistema proposto seria, portanto, conseguir que as ferramentas de data mining

trabalhassem em conjunto com as ferramentas de OLAP de uma data warehouse por forma a aumentar

a qualidade e rentabilidade da experiência para o utilizador, numa perspectiva a que foi dado o nome de

OLAP mining. Um dos principais desafios na criação de um sistema destes é a necessidade de uma

implementação eficiente do mecanismo de computação e construção do cubo, que permita uma

capacidade de resposta rápida. Com base no operador CUBE [Gray1997] e no algoritmo Multi-Way

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

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

computado, computar simultaneamente o maior número de agregados possível e retirar os agregados de

memória o mais cedo possível de forma a libertar memória para a computação de outros agregados

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

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

como tuplos. Para cada chunk, as células são mapeadas para um endereço de memória que pode ser

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

indexação para aceder aos chunks. No fundo, são combinadas características de sistemas ROLAP e

MOLAP num único algoritmo.

No trabalho realizado por Tam, o conceito de cubo foi desenhado tendo em conta um contexto dirigido

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

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

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

dimensional, é adicionado o valor ALL a cada dimensão Di, tal como descrito por [Gray1997], o que faz

com que qualquer célula em que o valor ALL faça parte do seu endereço corresponda a um agregado.

Este tipo de células é designado como célula cubóide (cuboid cell), enquanto as restantes células são

consideradas células nucleares (core cells). Os valores de cada dimensão são mapeados para

coordenadas de tal forma que a dimensão Di corresponda aos valores {di0, di1, ..., di|Di|-1, diALL}. A posição

de cada célula do cubo é denotada no espaço multidimensional pelo vector V(v0, v1, ..., vN-1), sendo a

magnitude de cada vector equivalente ao número de dimensões do cubo. Portanto, para uma célula

cubóide, o seu endereço contém pelo menos um componente vj tal que vj = |Dj|, j ≥ 0 e j < N. Assim, a

célula cujo endereço é dado pelo vector V(|D0|, ..., |DN-1|) trata-se da célula cubóide correspondente ao

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

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 =

1 e assim sucessivamente para i = 0,1, 2. A célula cubóide com o endereço V(5, 4, 3) corresponde,

então, à célula (ALL, ALL, ALL). Seguindo ainda esta notação, a célula com o endereço V(5, 0, 0) guarda

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)},

Page 37: Algoritmos para a Geração de Hipercubos

36

enquanto a célula com o endereço V(5, 4, 0) guarda o resultado da soma das medidas das células S1 =

{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,

0), V(4, 4, 0)}. Desta forma, a célula V(5, 4, 0) depende de dois conjuntos de células diferentes, ou seja,

S1 e S2 são sub-cubóides potenciais do cubóide V(5, 4, 0)

Figura 17 – Representação de um cubo 3D segundo [Tam1998]

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

ordenadas como mostra a tabela de tal forma que o endereço V(0, 0, 0) e V(0, 1, 0) estão nas posições 0

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

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

multidimensional e o espaço unidimensional é realizado pelos algoritmos Vector-To-Index e Index-To-

Vector [Tam1998].

Tabela 8 – Ordem das células do cubo no array [Tam1998]

V(0, 0, 0) V(0, 0, 1) ... V(0, 0, |D2|)

V(0, 1, 0) V(0, 1, 1) ... V(0, 1, |D2|)

... ... ... ...

V(0, |D1|, 0) V(0, |D1|, 1) ... V(0, |D1|, |D2|)

V(1, 0, 0) V(1, 0, 1) ... V(1, 0, |D2|)

... ... ... ...

V(|D0|, 2, 0) V(|D0|, 2, 1) ... V(|D0|, 2, |D2|)

... ... ... ...

V(|D0|, |D1|, 0) V(|D0|, |D1|, 1) ... V(|D0|, |D1|, |D2|)

Page 38: Algoritmos para a Geração de Hipercubos

37

Com base no algoritmo de Zhao et al, o array é dividido em chunks, cada um dos quais deve ter uma

dimensão que lhe permita existir em memória. No seguimento da notação utilizada, um chunk pode ser

um chunk nuclear (core chunk) ou um chunk cubóide (cuboid chunk). A maioria dos chunks cubóides são

pequenos e acedidos mais frequentemente, pelo que devem ser separados dos chunks nucleares para

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

mesmo volume, é necessário determinar qual o tamanho dos chunks. Para esse fim, é estabelecido um

limite e verifica-se se o tamanho da maior dimensão pode ser usado como limite para todas as

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

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

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

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

cubo C após ter sofrido chunking.

Figura 18 – Representação do cubo C com 18 chunks [Tam1998]

Cada chunk é tratado como um cubo, o que significa que conceptualmente existem dois modelos

multidimensionais: o modelo global, que determina os identificadores dos chunks, e o modelo local, que

determina os afastamentos (offsets) das células dentro de cada chunk. Logo, cada célula do cubo está

sempre associada a um vector global e um vector local, que podem ser obtidos a partir do endereço da

célula. Tendo em conta a divisão do cubo em chunks, a última célula cubóide do cubo C encontra-se em

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

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

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

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

Page 39: Algoritmos para a Geração de Hipercubos

38

D1 e D2 obtêm-se os segmentos 2 e 1, pelo que GV = (2, 2, 1). Quanto ao vector local LV = (lv0, lv1, lv2), é

calculado utilizando a fórmula

𝑙𝑣𝑖 = 𝑣𝑖 − 𝑠𝑖𝑗

𝑔𝑣𝑖−1

𝑗=0

, 0 ≤ 𝑖 ≤ 𝑁

em que sij é o número de células no segmento j da dimensão Di. Consequentemente, lv0 = 5 – (3 +2) = 0,

lv1 = 4 – (3 + 1) = 0 e lv2 = 3 – (3) = 0 [Tam1998].

No que se refere à computação de agregados propriamente dita, são utilizados os conceitos de MMST e

ordenamento óptimo da dimensão. O algoritmo Multi-Way consegue computar vários agregados

relacionados simultaneamente apenas com um varrimento dos dados e utilizando a quantidade mínima

de memória possível devido à ordenação óptima das dimensões. A figura abaixo mostra a MMST para o

cubo C com O = (D2, D1, D0) já que |D0| > |D1| > |D2|, em que os números sob cada nó denotam o número

de agregados que têm que ser mantidos em memória para que esse nó possa ser computado.

Figura 19 – MMST para o cubo C [Tam1998]

Em vez de utilizar a MMST como estrutura base, o trabalho de Tam propõe uma estutura similar

designada por árvore de cobertura mínima de número (minimum number spanning tree – MNST). Numa

MNST, as dimensões estão ordenadas de tal forma que |D0| ≥ |D1| ≥ |D2| ≥ ... ≥ |DN-1|, o que, por

definição, gera uma ordem óptima O = {DN-1, ..., D2, D1, D0}. Além disso, os níveis são numerados de tal

forma que o nível correspondente ao nó raiz é agora o nível 0, ou seja, o o nível aumenta à medida que

se desce na árvore [Tam1998]. A figura 15 mostra a MNST para o cubo C.

Page 40: Algoritmos para a Geração de Hipercubos

39

Figura 20 – MNST para o cubo C [Tam1998]

Qualquer nó M num nível i abaixo do nível 0 pode ser computado a partir dos nós no nível acima cujas

dimensões contenham todas as dimensões que compõem esse nó. Isto significa que pode existir mais

do que um nó a partir no nível i-1 a partir do qual o nó M pode ser computado. A razão da existência

desta estrutura prende-se com o facto de, em vez de seleccionar o nó no nível i-1 que permita calcular o

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

requer o menor número possível de células cubóides para se conseguir computar o nó M. Segundo esta

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

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

agregado e |D2| < |D1|. Como razões para o uso desta estrutura em detrimento da MMST, são indicadas

a maior facilidade na sua construção devido ao facto de não ser necessário realizar cálculos de

requisitos de memória, o facto de serem estruturas equivalente em termos de necessidades de memória

e da MNST permitir usar um menor número de subcubóides para computar um agregado.

Com base nestes conceitos, Tam propõe um algoritmo designado como R-cubing, cujo funcionamento é

explicado de seguida com base na MNST na figura 15. Como a célula em V(0, 0, 0) é uma célula

nuclear, a MNST é percorrida a partir do nó 012 no nível 0. Sabendo que o nó 012 pode ser computado a

partir dos nós 01, 02 e 12 segundo as dimensões D2, D1 e D0, respectivamente, a célula V(0, 0, 0) é

adicionada às células cubóides em V(0, 0, 3) segundo a dimensão D2, V(0, 4, 0) segundo a dimensão D1

e V(5, 0, 0) segundo D0. No total, estão três células cubóides em memória. O processo repete-se para a

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

que mais duas células cubóides sejam carregadas para memória. Da mesma forma, a célula nuclear em

V(0, 0, 2) é adicionada a V(0, 0, 3), V(0, 4, 2) e V(5, 0, 2), forçando o carregamento de mais duas células

cubóides para memória. Neste ponto, a célula cubóide em V(0, 0, 3) contém todas as somas

Page 41: Algoritmos para a Geração de Hipercubos

40

necessárias, pelo que é necessário verificar na MNST se esta célula é útil para o cálculo de outras. Na

MNST, este agregado corrresponde ao nó 01 e não possui quaisquer nós dependentes de si; logo, V(0,

0, 3) é guardado em disco e a memória associada libertada. As células nucleares em V(0, 1, 0), V(0, 1,

1), V(0, 1, 2), V(0, 2, 0), ..., V(0, 3, 1), V(0, 3, 2) são depois examinadas e adicionadas às

correspondentes células cubóides. Novamente, as células cubóides em V(0, 1, 3), V(0, 2, 3) e V(0, 3, 3)

estão completas e podem ser guardadas em disco. Note-se que, aquando da leitura da célula nuclear

V(0, 3, 0), o valor que contém vai ser adicionado à célula cubóide em V(0, 4, 0), o que faz com que esta

célula esteja completa. Segundo a MNST, esta célula cubóide refere-se ao nó 02 e dele dependem o nó

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

processo, tal como ilustrado na figura 16, é repetido para cada célula nuclear e cubóide até que todas as

células nucleares tenham sido percorridas e todas as células cubóides tenham sido materializadas

[Tam1998]. Como se pôde verificar, antes de uma célula cubóide ser guardada e a memória associada

libertada tem que cumprir dois requisitos: essa célula deve ter sido completamente materializada, ou

seja, deve conter o resultado da soma de todas as células subcubóides correspondentes e já deve ter

sido adicionada a todos os cubóides que dela dependem.

Figura 21 – Relação entre cubóides e subcubóides em relação à célula V(0, 0, 0) usando R-cubing [Tam1998]

Porém, tal como referido anteriormente, o conceito de cubo implementado por Tam é o de um cubo

baseado em chunks, pelo que em vez de uma célula ser adicionada a outra na realidade um chunk

subcubóide é adicionado a outro chunk subcubóide. Segundo o algoritmo proposto, o chunk 0 é

Page 42: Algoritmos para a Geração de Hipercubos

41

adicionado ao chunk 12 segundo D0, ao chunk 4 segundo D1 e ao chunk 1 segundo D2, tal como mostra

a figura 17. No fundo, o processo de somar um chunk subcubóide a outro equivale a comprimir esse

subcubóide segundo uma dimensão Da de tal forma que o vector local da célula subcubóide do chunk

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),

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

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

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

adicionadas à célula 5 do chunk 1 (LV(1, 2, 0)) segundo a dimensão D2.

Figura 22 – Processo de adição do chunk 0 aos chunks subcubóides relacionados [Tam1998]

Conclui-se, assim, que Tam não implementou o algoritmo Multi-Way tal como proposto por Zhao et al

[Zhao1997], mas antes que se baseou em conceitos básicos, como o chunking, o ordenamento óptimo

das dimensões e a MMST para desenvolver e implementar um algoritmo que combina características

tanto da abordagem ROLAP como da abordagem MOLAP. Apesar de provavelmente ter realizado

previamente um estudo sobre o algoritmo Multi-Way como forma de analisar os seus pontos fortes e

fracos, não existem quaisquer dados sobre esse estudo ou a implementação usada para tal. No final do

seu trabalho, é feita uma comparação entre o algoritmo implementado e o algoritmo Multi-Way apenas

em termos do tempo de execução, que mostra que ambos os algoritmos têm um desempenho

semelhante para conjuntos de dados com baixo número de dimensões e que o desempenho do

Page 43: Algoritmos para a Geração de Hipercubos

42

algoritmo Multi-Way se deteriora quando aumenta o número de dimensões em consequência do elevado

custo associado à construção da MMST [Tam1998].

2.5 Variantes ao problema tradicional

Os trabalhos mais recentes na área de OLAP e geração de hipercubos incidem sobre uma variante do

problema tradicional da computação de cubos. Como se viu, o problema tradicional consiste, muito

resumidamente, em calcular todos os agregados da forma mais eficiente possível, tendo em conta que o

problema é exponencial em relação ao número de dimensões consideradas. Além disso, há que ter em

atenção que o tamanho de cada agregado depende da cardinalidade das dimensões que o compõem.

Como os dados reais tendem a ser de natureza esparsa, uma estratégia para aumentar o desempenho

dos algoritmos nessas situações passa por identificar antes da computação quais os subconjuntos de

interesse [Beyer1999] apresentaram uma variante ao problema tradicional da geração de cubos a que

deram o nome de cubos iceberg (iceberg cubes). O problema icerberg-CUBE consiste em computar

todas as agregações para todas as combinações de atributos que satisfazem uma determinada

condição, à semelhança da cláusula HAVING numa interrogação SQL. Tendo em conta o contexto de

dados esparsos, a condição envolvida estabelece que uma partição deve ter pelo menos N tuplos, sendo

N designado como o suporte mínimo da partição.

2.5.1 Computação da base para o topo (bottom-up computation)

Beyer e Ramakrishnan propuseram o algoritmo BUC como resposta ao problema dos cubos iceberg.

Este algoritmo procura combinar a eficiência a nível de entradas/saídas do algoritmo Partitioned-Cube

com a possibilidade de recorrer a filtragem em função do suporte mínimo pretendido [Beyer1999]. A sua

designação deve-se ao facto do algoritmo começar nos agregados mais pequenos e prosseguir até aos

agregados maiores, ao contrário da maioria dos restantes algoritmos. Cada dimensão é lida e dividida

segundo o número de ocorrências para cada um dos valores dessa dimensão, sendo as restantes

dimensões computadas recursivamente para cada partição.

O algoritmo recorre à estratégia dividir para conquistar (divide-and-conquer) uma vez que, após uma

determinada partição ter sido calculada, todos os cubóides descendentes são calculados antes do

algoritmo passar à partição seguinte. O movimento da base para o topo, ou seja, no sentido dos

agregados mais pequenos para os agregados maiores, permite que seja realizada uma filtragem

recorrendo à propriedade anti-monotónica empregue no algoritmo Apriori, usado na descoberta de

associações frequentes entre objectos [Agrawal1994] que estabelece que, se a contagem numa célula c

de um cubóide A é inferior a um limite mínimo estabelecido, então o valor para qualquer uma das células

que partilhem com essa célula um prefixo comum nunca será superior ao limite pré-estabelecido; logo,

essas células descendentes não precisam de ser calculadas.

Page 44: Algoritmos para a Geração de Hipercubos

43

Os resultados mostram que o algoritmo BUC apresenta melhor desempenho na computação de cubos

esparsos do que o algoritmo Memory-Cube [Beyer1999].

2.5.2 H-cubing

Han et al [Han2001]propuseram um algoritmo orientado para a resolução do problema dos cubos iceberg

mas para a situação específica em que a condição a ser satisfeita pelos agregados envolve uma medida

não distributiva, como a média. O recurso a este tipo de medidas, que normalmente não obedecem à

propriedade anti-monotónica, faz com que não possa ser feito filtragem com base nessa propriedade. No

caso concreto da média, o facto de o valor médio numa célula c de um cubóide A ser inferior a um valor

mínimo pré-definido não significa obrigatoriamente que o valor das células descendentes seja igualmente

inferior.

O algoritmo proposto utiliza uma estrutura em árvore (H-tree) baseada na FP-tree usada pelo algoritmo

FP-growth [Han1999]. São características desta estrutura o facto de poder ser construída com um único

varrimento da base de dados e a sua completude, no sentido em que a H-tree e respectiva tabela

(header table) fornecem toda a informação necessária para calcular um cubo iceberg. Cada nível da

árvore representa uma dimensão no cubóide base e cada tuplo de d-dimensões compõe um caminho

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

entre si. A cada nível está associada uma tabela (header table) que regista a frequência de cada um dos

valores possíveis das dimensões e mantém ligações aos primeiros nós correspondentes a esses valores.

Figura 23 - Exemplo de uma H-tree [Agrawal1994]

Page 45: Algoritmos para a Geração de Hipercubos

44

A partir desta estrutura, o cubo pode ser calculado da base para o topo (bottom-up) ou do topo para a

base (top-down). Em qualquer das estratégias, o algoritmo começa num determinado nível da árvore e

analisa todos os agregados que incluem a dimensão correspondente a esse nível e as dimensões

correspondentes aos níveis superiores. A agregação é facilitada pela tabela (header table): se o valor

para um determinado nó é inferior ao mínimo estabelecido, a agregação ―salta‖ para o próximo nó

através do ponteiro lateral. A diferença entre as duas estratégias é o ponto de entrada do algoritmo, que

é na base da árvore no caso da direcção ascendente (bottom-up) e no topo da árvore no caso da

direcção descendente (top-down).

Uma das vantagens deste algoritmo reside exactamente na estrutura da H-tree que, ao eliminar a

duplicação de dados, permite que se tire partido da computação simultânea de agregados e que sejam

calculadas menos combinações de dimensões.

2.5.3 Star-Cubing

Xin et al propuseram um algoritmo que procura combinar os pontos fortes dos algoritmo Multi-Way, BUC

e H-Cubing. Basicamente, o algoritmo Star-Cubing integra as potencialidades da computação da base

para o topo (bottom-up) e do topo para a base (top-down) com algumas técnicas de optimização do

desempenho. No que se refere à ordem de computação global, utiliza um modelo do topo para a base

(top-down) e este é complementado por uma abordagem da base para o topo (bottom-up) implementada

por uma camada inferior do algoritmo. Esta integração permite que o algoritmo consiga efectuar

agregações sobre várias dimensões sem perder a capacidade de dividir os agregados pais e realizar

filtragem sobre os agregados filhos que não respeitam a condição iceberg [Xin2003].

Uma das optimizações introduzidas passa pelo conceito de dimensões partilhadas, que facilita a

agregação partilhada. Observando a figura 24, verifica-se que todos os nós da árvore mais à esquerda

incluem as dimensões ABC, todos os nós na segunda sub-árvore incluem as dimensões AB e todos os

nós na terceira sub-árvore incluem a dimensão A. A estas dimensões comuns em várias sub-árvores dá-

se o nome de dimensões partilhadas.

Figura 24 - Árvore de computação top-down [Xin2003]

Page 46: Algoritmos para a Geração de Hipercubos

45

Como as dimensões partilhadas podem ser identificadas numa fase inicial, isso significa que pode ser

avaliada a necessidade de computar determinados agregados posteriormente. Se a condição iceberg for

anti-monotónica e o valor agregado numa dimensão partilhada não satisfizer essa condição, todos os

agregados que estendem essa dimensão partilhada não satisfazem igualmente a condição e, como tal,

não precisam de ser computados. Esta capacidade de conseguir determinar o mais cedo possível

durante a computação que determinados agregados não necessitam de ser calculados é outra das

optimizações importantes integradas no algoritmo. Outra optimização relevante é o uso de uma estrutura

semelhante à H-tree mas com maior capacidade de compressão (star-tree).

Os resultados a nível de desempenho para este algoritmo foram semelhantes aos conseguidos pelo

algoritmo Multi-Way para cubos completos e melhores que os obtidos pelos vários algoritmos para cubos

esparsos, em grande parte devido ao facto do algoritmo conseguir integrar várias optimizações.

Page 47: Algoritmos para a Geração de Hipercubos

46

3 Trabalho realizado

Esta secção descreve os principais aspectos da implementação realizada e as alterações propostas ao

algoritmo Multi-Way no sentido de aumentar a capacidade de gestão de memória do mesmo e,

consequentemente, o número de situações em que pode ser aplicado.

3.1 Motivação

O estudo dos trabalhos realizados nesta área mostra que a computação de agregados multidimensionais

e agregados é uma operação fundamental no que se refere às aplicações OLAP, tendo sido concebidos

diferentes algoritmos e estratégias de optimização para esse fim. Porém, muitos dos algoritmos

anteriormente apresentados foram desenvolvidos para sistemas ROLAP, sendo o número de algoritmos

desenhados para sistemas MOLAP bastante inferior. Os sistemas do tipo MOLAP são mais afectados

pelo carácter esparso dos dados, uma situação frequente na vida real, mas conseguem alcançar uma

eficiência semelhante à dos algoritmos para sistemas ROLAP desde que sejam aplicadas técnicas que

lhes permitam lidar com esse tipo de dados ou quando são aplicados a conjuntos de dados de pequena

ou média dimensão.

O algoritmo Multi-Way foi proposto por Zhao et al [Zhao1997] exactamente na sequência da ausência de

trabalhos nesta área. A ideia básica deste algoritmo reside no aproveitamento das características

inerentes a este tipo de sistemas, que pela sua própria organização dispensam a necessidade de

reordenar atributos e efectuar agrupamentos de forma a que os primeiros agregados calculados possam

servir de base ao cálculo de agregados posteriores: o truque consiste em percorrer os valores das

dimensões, armazenados em posições fixas, da forma mais eficiente possível e calcular

simultaneamente o máximo de agregados parciais espacialmente delimitados que for possível. O

principal problema que se põe a esta abordagem está relacionado com a forma como os arrays vão ser

geridos, uma vez que é necessário carregar e armazenar arrays que provavelmente ultrapassam a

capacidade de memória existente. Para resolver os problemas de gestão de memória, os autores

propuseram o uso de chunking, por forma a dividir arrays n-dimensionais em fragmentos n-dimensionais

mais pequenos que podem ser armazenados como um único objecto.

Os princípios básicos deste algoritmo, tais como a ordenação óptima, o chunking e a MMST, estiveram

na base de um algoritmo desenvolvido e implementado por Tam [Tam1998], tal como explicado no

decorrer da secção anterior. Embora na prática o algoritmo se afaste do que foi proposto por Zhao et al,

continua a ser um exemplo válido de uma implementação possível baseada nesse conjunto de

princípios, apesar de direccionada e optimizada para um fim específico. Porém, independentemente dos

bons resultados conseguidos, o algoritmo continua a apresentar limitações uma vez que apenas

consegue computar cubos com pequena a média dimensão (com menos de dez dimensões) [Tam1998].

Tendo em conta a escassez de trabalhos direccionados para sistemas MOLAP e os bons resultados

alcançados por este algoritmo, considerou-se que seria interessante focar o trabalho sobre o algoritmo

Page 48: Algoritmos para a Geração de Hipercubos

47

Multi-Way. Além do algoritmo proposto e do relatório do trabalho realizado por Tam, não existe qualquer

outra informação disponível sobre este algoritmo, assim como não foi possível ter acesso à

implementação realizada. Assim sendo, o objectivo deste trabalho consiste em fazer um estudo

aprofundado do algoritmo Multi-Way, com base na implementação realizada segundo a proposta de

[Zhao1997], e tentar introduzir nessa implementação optimizações que permitam ao algoritmo ser

efectivo para maiores volumes de dados e maiores dimensionalidades.

3.2 Arquitectura

Neste contexto, um cubo multidimensional é representado por dois vectores unidimensionais, em que um

tem comprimento igual ao número de dimensões existentes nos dados e mantém em cada posição a

cardinalidade da dimensão respectiva e o outro tem comprimento igual ao produto das cardinalidades

das dimensões envolvidas e mantém os valores computados. O vector que guarda a informação sobre

as dimensões fá-lo obedecendo à ordenação óptima definida por Zhao et al [Zhao1997]. Esse vector

funciona como um vector de controlo na medida em que permite recuperar os valores que estão

guardados no outro vector, usando uma função de conversão. Assumindo que temos um cubo com 3

dimensões |A| = 2, |B| = 3, |C| = 4 e pretendemos aceder à posição (2, 1, 0) no vector de dados, a

posição correspondente no vector unidimensional é dada pelo produto entre as cardinalidades de cada

uma das dimensões e a coordenada que se pretende converter relativa a essa dimensão (2 + (3 x 1) +

2 x 3 x 0 = 5). Esta abordagem permite que seja utilizado qualquer tipo de função de cálculo pois esta foi

definida a partir de uma classe genérica abstracta. Para tal, apenas é necessário derivar uma classe

específica para a função pretendida.

No que se refere à forma como os dados são mantidos e utilizados pelo algoritmo, estes são mantidos

numa tabela da base de dados que simula uma tabela de factos. Essa tabela é composta por um

identificador do agregado, uma coluna por dimensão que representa a posição relativa no agregado e o

valor correspondente a essa posição para esse agregado. A tabela abaixo mostra uma utilização

possível para essa tabela, assumindo que temos um cubo com as dimensões A, B e C em que |A| = |B| =

|C| = 3. Ao lado de cada tuplo, está indicado o cubóide a que se refere. Como se pode verificar, existem

várias entradas para o mesmo cubóide, na medida em que cada linha corresponde a uma posição

diferente nesse cubóide. A necessidade do identificador advém do facto de existirem entradas com

valores iguais para diferentes cubóides. Como exemplo, temos as linhas 7 e 15, em que os valores para

as várias colunas são iguais (2, 0, 0, ..., 0) mas se referem a cubóides diferentes (AB e BC

respectivamente). Desta forma, consegue-se representar qualquer elemento de qualquer cubóide.

Page 49: Algoritmos para a Geração de Hipercubos

48

Tabela 9 – Exemplo de notação utilizada para identificar os agregados e seus elementos

Identificador Col001 Col002 Col003 Col004 ... Col010 Valor

AB L000001 0 0 0 0 ... 0 3

AB L000001 0 1 0 0 ... 0 7

AB L000001 0 2 0 0 ... 0 1

AB L000001 1 0 0 0 ... 0 5

AB L000001 1 1 0 0 ... 0 8

AB L000001 1 2 0 0 ... 0 6

AB L000001 2 0 0 0 ... 0 10

AB L000001 2 1 0 0 ... 0 2

AB L000001 2 2 0 0 ... 0 3

AC L000002 0 0 0 0 ... 0 9

AC L000002 0 0 0 0 ... 0 11

... … ... ... … ... ... ... ...

AC L000002 1 2 0 0 ... 0 13

... … ... ... … ... ... ... ...

BC L001002 2 0 0 0 ... 0 12

... … ... ... … ... ... ... ...

Actualmente, a tabela possui no máximo dez colunas, uma vez que as tabelas têm que ser construídas

com um número limite de colunas. Porém, este valor não coloca qualquer limitação ao algoritmo na

medida em que este não depende do número de colunas da tabela, que pode ser facilmente alterado,

visto que recebe à partida o número de dimensões a tratar.

3.3 Optimização de “sub-treeing”

O conceito de árvore mínima de cobertura (MMST) para um determinado ordenamento das dimensões é

central no algoritmo, uma vez que assegura que é alocada a quantidade mínima de memória necessária

para esse ordenamento das dimensões. A ideia desta optimização passa por optimizar o funcionamento

do algoritmo quando se pretende calcular um determinado agregado, uma vez que a topologia do próprio

algoritmo obriga a refazer os cálculos sempre que é realizada um operação OLAP, como drill-down e roll-

up. Logo, quando se pretende calcular um determinado agregado, não há necessidade de calcular todos

os agregados correspondentes a cada um dos nós da árvore mas somente aqueles que são estritamente

necessários, ou seja, não é necessário calcular toda a árvore mas apenas uma porção desta (sub-tree).

A figura 25 mostra o pseudocódigo correspondente à implementação da MMST. Para que a árvore

pudesse suportar esta optimização, foi necessário planear uma forma de marcar os nós que são

necessários para calcular um agregado por forma a que se distingam dos restantes e possam assim ser

Page 50: Algoritmos para a Geração de Hipercubos

49

facilmente seleccionados para cálculo, o que é conseguido através de uma propriedade que mantém em

cada nó da árvore a referência do seu nó pai.

noRaiz {D1,D2,...,Dn}

listaNos {}

initMMSTree()

listaFilhos {}

genFilhos(noRaiz)

genFilhos(ListaDimensões noPai)

pai noPai

i n

para cada Di em noPai

noFilho noPai excluindo Di

se(not noFilho listaNos)

listaNos listaNos noFilho

listaFilhos listaFilhos noFilho genFilhos(noFilho)

i i-1

Figura 25 – Pseudocódigo correspondente à criação da MMST

Para implementar esta optimização, é necessário recorrer a um mecanismo básico de descoberta de

caminho (path finding) que permita assinalar quais os nós da árvore que é necessário calcular por forma

a conseguir obter um determinado agregado. Para este efeito, os nós são marcados desde o nó

objectivo (calculate = true) até à raiz. Para agilizar o varrimento da árvore, cada nó mantém uma

referência para o nó pai imediatamente acima na árvore, à excepção do nó raiz em que o valor da

propriedade father é nulo.Um exemplo da utilidade desta implementação pode ser facilmente

concretizado, tendo em conta a MMST da figura 26. Segundo o algoritmo original, para calcular o valor

de ALL é necessário calcular um total de quinze agregados antes de obter o valor de ALL, ou seja, é

necessário calcular o valor dos agregados correspondentes a cada um dos nós da árvore. Utilizando

sub-treeing, o valor do agregado ALL pode ser obtido calculando apenas quatro agregados uma vez que

apenas é obrigatório calcular o valor correspondente aos nós ALL, A (father(ALL) = A), AB

(father(A) = AB) e ABC (father(AB) = ABC).

Page 51: Algoritmos para a Geração de Hipercubos

50

Figura 26 – Exemplo de uma MMST para O = (A, B, C, D)

O objectivo desta optimização passa por reduzir o número de nós que é necessário computar para obter

um determinado agregado de uma forma simples, o que terá impacto sobre o tempo necessário para

computar esse agregado visto eliminar a computação de nós que não interferem directamente no cálculo.

Esta optimização não tem qualquer correspondência no trabalho realizado por Tam [Tam1998] uma vez

que este se baseia na MNST para gerir a sequência de computação dos agregados.

3.4 Optimização de “sub-chunking”

Tal como referido anteriormente, os arrays de grandes dimensões devem ser armazenados divididos em

chunks, por questões de eficiência e desempenho. Esta estratégia permite que todas as dimensões

sejam tratadas de forma uniforme, uma vez que o chunking permite dividir um array n-dimensional em

vários chunks n-dimensionais que podem ser armazenados em disco.

Um dos principais problemas que se coloca tanto a este algoritmo como aos restantes algoritmos da

área é a quantidade de memória que requerem para poder calcular os agregados. Em resultados dos

testes efectuados à sua implementação, Tam refere que o seu algoritmo não conseguia completar os

cálculos para volumes de dados superiores a 240000 tuplos com 6 dimensões, apenas conseguindo

computar cubos com maior número de dimensões para menores volumes de dados [Tam1998].

Tendo em conta a árvore da figura 26, verifica-se que o pior caso corresponde ao cálculo do agregado

ABC, que necessita de um total de blocos de memória equivalente ao produto da cardinalidade das n-1

primeiras dimensões segundo a ordem O (10 x 100 x 1000 = 1000000 blocos de memória). A solução

passa por criar um sub-chunk mais pequeno recorrendo ao máximo divisor comum (MDC) das cardinalidades

das dimensões, o que para o exemplo anterior resultaria num total de 10 x 10 x 10 = 1000 blocos de memória.

Desta forma, é necessário guardar para suporte persistente cada um dos sub-chunks para garantir que os

resultados não são alterados e recuperar o sub-chunk pretendido quando se pretende mudar para outro. Isto

Page 52: Algoritmos para a Geração de Hipercubos

51

acarreta forçosamente uma carga a nível de operações de entrada/saída que tem impacto na velocidade de

desempenho do algoritmo, mas que é compensada pelo facto de se conseguir realizar cálculos que doutra

forma não seriam fazíveis. O uso do MDC assegura que é criado o maior bloco possível e garante assim que é

realizado o número mínimo possível de operações de leitura e escrita. Nos casos em que esta estratégia não

permite ainda que o cálculo seja efectuado por falta de memória, é criado um novo sub-chunk cuja dimensão

resulta do quociente entre o máximo divisor comum (MDC) e o mínimo divisor comum (mDC). No pior dos

casos, cada um dos novos sub-chunks corresponderá a 1 bloco de memória, mais uma vez assegurando que

o cálculo pode ser efectuado em detrimento do desempenho.

Convém sublinhar que todo este processo não altera em nada a lógica de funcionamento do algoritmo tal

como foi proposto, uma vez que a necessidade de mudança de um sub-chunk para outro é gerida pelo próprio

nó da MMST: cada nó conhece a dimensão do seu sub-chunk e a base actual e sempre que detecta que o

elemento a tratar está fora do âmbito do sub-chunk em memória ordena o carregamento do sub-chunk

adequado.

dim {D1,D2,...,Dn}

maxDC MDC(dim)

mDC mDC(dim)

chunk maxDC

tam D1 x D2 x ... x Dn-1

MAX número máximo de blocos de memória possível

base {b1,b2,...,bn}

loc {l1,l2,...,ln}

enquanto(tam > MAX)

chunk maxDC/mDC

tam chunkn-1

para cada Di em loc

se(li > bi li < bi) guardaSubChunk(loc)

lêSubChunk(loc)

actualiza(loc,val)

Figura 27 - Pseudocódigo que ilustra o mecanismo de sub-chunking

Page 53: Algoritmos para a Geração de Hipercubos

52

4 Estudo do algoritmo Multi-Way

Esta secção descreve os resultados obtidos na sequência do estudo do algoritmo Multi-Way, incluindo

também os efeitos das optimizações propostas na secção 3. Para realizar o estudo, foram realizados

testes no sentido de avaliar a influência da densidade dos dados e do volume dos dados sobre o

algoritmo com e sem as optimizações propostas. A nível da análise da influência do volume de dados,

foram ainda estudados dois níveis de variação diferentes devido à natureza específica do problema, ou

seja, o volume de dados submetidos ao algoritmo foi variado tanto em termos do número de dimensões

existentes como em termos do número de valores comportados por cada dimensão. Na sequência dos

testes, foram recolhidos dados sobre o número de leituras e escritas realizadas na base de dados, o

tempo de execução total e individualizado para cada etapa do algoritmo e o número de nós da estrutura

base explorados para realizar o cálculo do cubo.

4.1 Dados de teste

Os dados utilizados para realizar o estudo do algoritmo foram gerados recorrendo ao projecto Illimine2.

Trata-se de um projecto mantido pelo grupo de pesquisa em exploração de dados (data mining) da

Universidade de Illinois liderado pelo professor Jiawei Han que reúne diversas ferramentas nas áreas de

data mining e aprendizagem, disponibilizando mesmo via internet demonstrações de alguns dos

principais algoritmos nessa área. Igualmente disponibilizado por este projecto está um gerador aleatório

de dados, no qual o utilizador pode especificar o número de transacções que pretende, o número de

dimensões e a cardinalidade de cada dimensão.

Seguidamente, foi definido um plano de testes que nos permitisse avaliar os aspectos referidos

anteriormente, nomeadamente a influência da densidade e quantidade de dados submetidos ao

algoritmo, tal como mostra a tabela abaixo. Cada um dos testes, à execpção dos testes T1 a T4

inclusivé, foi executado para a implementação realizada do algoritmo original (MW), para a

implementação com cada uma das optimizações propostas (MW + SC e MW + ST) e para a

implementação reunindo as duas optimizações (MW + SC + ST). Em cada um dos testes, procedeu-se

ao cálculo do agregado ALL por forma a forçar o algoritmo a percorrer o maior número possível de níveis

da MMST e utilizar o maior bloco de memória necessário para efectuar esse cálculo.

2 http://illimine.cs.uiuc.edu

Page 54: Algoritmos para a Geração de Hipercubos

53

Tabela 10 – Plano de testes

Teste Nº de transacções Dimensões Cardinalidades

T1 60000 4 10 20 30 40

T2 120000 4 10 20 30 40

T3 180000 4 10 20 30 40

T4 240000 4 10 20 30 40

T5 5000 3 10 10 10

T6 5000 4 10 10 10 10

T7 5000 5 10 10 10 10 10

T8 5000 3 10 10 10

T9 5000 3 20 20 20

T10 5000 3 30 30 30

T11 5000 3 40 40 40

T12 5000 3 50 50 50

T13 5000 3 60 60 60

T14 5000 3 70 70 70

T15 5000 3 80 80 80

T16 5000 3 90 90 90

Em seguida apresentam-se os resultados obtidos após a concretização do plano de testes apresentado

na tabela 9, assim como a análise dos mesmos. Os testes foram realizados num Pentium IV a 3Ghz com

1 Gb de memória, com sistema operativo Windows XP Professional.

4.2 Estudo do efeito da variação na densidade dos dados

Para avaliar o impacto da variação da densidade dos dados no desempenho do algoritmo, foram

realizados os testes T1 a T4. Como se pode observar tendo em atenção as características dos ficheiros

utilizados, todos eles apresentam o mesmo número de dimensões com a mesma cardinalidade. A

variação na densidade foi conseguida variando o número de transacções consideradas. Os ficheiros

para os testes T1, T2 e T3 foram depois obtidos usando uma percentagem crescente do número máximo

de transacções dado pelo produto das cardinalidades das dimensões (10 x 20 x 30 x 40 = 240000),

respectivamente 25%, 50% e 75% desse valor. O gráfico abaixo mostra os resultados obtidos para os

testes T1 a T4 no que se refere ao número total de leituras e escritas realizadas na base de dados pela

implementação do algoritmo original.

Page 55: Algoritmos para a Geração de Hipercubos

54

Figura 28 – Efeito da variação da densidade dos dados no número de leituras e escritas efectuadas por MW

Como se pode constatar da observação do gráfico, independentemente da densidade dos dados, o

algoritmo efectua sempre o mesmo número de operações de leitura e escrita. Embora este facto possa à

partida parecer desconcertante, decorre da própria lógica de funcionamento do algoritmo, já que é feito

um varrimento de todas as dimensões, começando na dimensão de maior cardinalidade, e visitadas

todas as posições, uma vez que não se dispõe de qualquer informação sobre o seu conteúdo.

Consequentemente, o número de operações de leitura e escrita realizadas pelo algoritmo apenas

depende do produto das cardinalidades das dimensões envolvidas, desde que os dados apresentem o

mesmo número de dimensões . O mesmo raciocínio se aplica ao gráfico da figura 29, que apresenta os

tempos de cálculo do cubo para diferentes densidades dos dados de entrada.

Figura 29 – Efeito da variação da densidade dos dados no tempo usado por MW para calcular o cubo

0 50000 100000 150000 200000 250000 300000 350000

T1

T2

T3

T4

Escritas

Leituras

00:01:00

00:01:17

00:01:35

00:01:52

00:02:09

00:02:26

00:02:44

T1 T2 T3 T4

Page 56: Algoritmos para a Geração de Hipercubos

55

Uma vez que as restantes implementações do algoritmo seguem a mesma filosofia por se basearem

nele, as conclusões obtidas seriam exactamente as mesmas no que se refere à influência da densidade

dos dados no desempenho do algoritmo.

4.3 Estudo do efeito da variação do volume de dados A variação do volume de dados pode ser consequência da variação do número de dimensões que

compõem os dados ou da variação da cardinalidade das dimensões envolvidas, pelo que é necessário

analisar cada uma das situações separadamente.

4.3.1 Efeito da variação do número de dimensões

Para avaliar o impacto da variação da densidade dos dados no desempenho do algoritmo, foram

realizados os testes T5 a T7, cujos resultados são apresentados de seguida. O gráfico 30 apresenta os

resultados dos testes para o algoritmo MW, enquanto os gráficos 31 e 32 fazem o comparativo entre os

resultados obtidos para as diferentes implementações.

Figura 30 – Efeito da variação do número de dimensões nas leituras e escritas realizadas para o algoritmo MW

T5 T6 T7

Leituras 1330 14640 161050

Escritas 836 9596 66006

0

20000

40000

60000

80000

100000

120000

140000

160000

180000

Page 57: Algoritmos para a Geração de Hipercubos

56

Figura 31 – Efeito da variação do número de dimensões nas leituras e escritas realizadas

Como se pode verificar da observação dos gráficos, o número de leituras e escritas aumenta quando

aumenta o número de dimensões consideradas. Porém, esta variação é explicada pelo facto de, quando

existem mais dimensões, existem consequentemente mais agregados, que por sua vez correspondem a

um maior número de nós na MMST. Da mesma forma, é possível observar que, sempre que se utilize

sub-treeing (ST), o número de leituras e escritas é inferior ao verificado para a implementação original,

uma vez que o objectivo desta optimização é exactamente diminuir o número de nós que é necessário

explorar para calcular um determinado agregado, reduzindo consequentemente esse tipo de operações.

Adicionalmente, verifica-se que sempre que se utiliza apenas sub-chunking (SC) há um aumento no

número de leituras e escritas, que advém do facto de ser necessário subdividir blocos de memória e isso

implicar um maior número de leituras e escritas intermédias na base de dados para se computar o

mesmo agregado. Quando as duas optimizações são utilizadas em conjunto, verifica-se uma melhoria

T5 T6 T7

MW 1330 14640 161050

MW+ST 1110 11110 111110

MW+SC 1330 14640 226210

MW+ST+SC 1110 11110 124960

0

50000

100000

150000

200000

250000

Leituras

T5 T6 T7

MW 836 9596 66006

MW+ST 616 6066 16066

MW+SC 836 9596 126211

MW+ST+SC 616 6066 24961

0

20000

40000

60000

80000

100000

120000

140000

Escritas

Page 58: Algoritmos para a Geração de Hipercubos

57

em relação ao original mas uma deterioração em relação à implementação que apenas utiliza sub-

treeing.

Outra medida com interesse para o estudo do efeito da variação do número de dimensões corresponde à

contabilização dos nós da MMST que são explorados por cada uma das implementações do algoritmo.

As figuras 32 e 33 mostram o efeito da variação do número de dimensões no número de nós explorados

para o algoritmo MW e para as diferentes implementações, respectivamente.

Figura 32 - Efeito da variação do número de dimensões no número de nós da MMST explorados para o algoritmo MW

Figura 33 – Efeito da variação do número de dimensões no número de nós da MMST explorados

Verifica-se facilmente, tal como seria esperado, que a um maior número de dimensões nos dados

corresponde igualmente um maior número de nós da MMST explorados, tal como referimos na análise

T5 T6 T7

MW 8 16 32

0

5

10

15

20

25

30

35

T5 T6 T7

MW 8 16 32

MW+ST 4 5 6

MW+SC 8 16 32

MW+SC+ST 4 5 6

0

5

10

15

20

25

30

35

Page 59: Algoritmos para a Geração de Hipercubos

58

dos gráficos anteriores. Esse acréscimo é mais acentuado nas implementações que não empregam

sub-treeing, o que confirma novamente o que havíamos constatado na análise do gráfico anterior.

O gráfico seguinte ilustra a influência do aumento do número de dimensões no tempo necessário para o

algoritmo calcular o agregado ALL. Como se pode verificar, o tempo dispendido nesse cálculo aumenta

com o número de dimensões envolvidas, o que confirma igualmente os resultados apresentados por

Tam [Tam1998].

Figura 34 – Efeito da variação do número de dimensões no tempo de cálculo do cubo

É vísivel que o tempo de execução do algoritmo é sempre superior para as implementações que

empregam a optimização de sub-chunking, o que seria expectável. Para volumes de dados menores,

essas alterações não são tão notórias, tornando-se mais vísiveis para volumes de dados maiores.

Verifica-se também que o desempenho é inferior quando se utiliza apenas sub-chunking do que quando

se utilizam ambas as optimizações. Isto deve-se ao facto de a introdução do sub-treeing apenas trazer

benefícios a nível do desempenho, na medida em que permite reduzir o número de nós explorados na

árvore, mas a introdução do sub-chunking gerar uma degradação a nível do desempenho do algoritmo,

na medida em que o facto de ser necessário subdividir blocos de memória implica um maior número de

leituras e escritas na base de dados, tal como comprovado nos gráficos 30 e 31.

4.3.2 Efeito da variação da cardinalidade das dimensões

Para avaliar o impacto da variação da densidade dos dados no desempenho do algoritmo, foram

realizados os testes T8 a T16. Tendo em conta o objectivo destes testes, não são apresentados

resultados relativos ao número de nós explorados visto que, tal como mostrámos na secção 4.2, o

número de nós explorados mantém-se constante desde que o número de dimensões envolvidas seja o

mesmo, que se verifica nesta situação.

00:00:00

00:00:17

00:00:35

00:00:52

00:01:09

00:01:26

00:01:44

00:02:01

MW MW+ST MW+SC MW+ST+SC

T5

T6

T7

Page 60: Algoritmos para a Geração de Hipercubos

59

As figuras 35 e 36 mostram o efeito da variação da cardinalidade das dimensões no número de leituras e

escritas realizadas pelo algoritmo para diferentes optimizações, respectivamente.

Figura 35 – Efeito da variação da cardinalidade das dimensões no número de leituras efectuadas

Figura 36 - Efeito da variação da cardinalidade das dimensões no número de escritas efectuadas

Constata-se que, à medida que aumenta a cardinalidade das dimensões envolvidas, o número de

leituras e escritas aumenta também drasticamente, sendo o acréscimo no número de leituras sempre

T8 T9 T10 T11 T12 T13 T14 T15 T16

MW 1330 9260 29790 68920 132650 226980 357910 531440 571280

MW+ST 1110 8420 27930 65640 127550 219660 347970 518480 538880

MW+SC 1330 9260 31710 72280 183050 249660 453670 571280 753570

MW+SC+ST 1110 8420 28920 67360 155000 231360 399000 538880 737190

1

10

100

1000

10000

100000

1000000

Leituras

T8 T9 T10 T11 T12 T13 T14 T15 T16

MW 836 3238 5766 7896 10626 13956 17886 22416 59281

MW+ST 616 2398 3906 4616 5526 6636 7946 9456 26881

MW+SC 836 3238 4711 8281 58051 33661 110671 59281 27546

MW+SC+ST 616 2398 1921 3361 30001 15361 56001 26881 11166

1

10

100

1000

10000

100000

1000000

Escritas

Page 61: Algoritmos para a Geração de Hipercubos

60

superior ao aumento do número de escritas. Mantem-se a tendência verificada nos testes anteriores, em

que a implementação que apenas emprega sub-treeing realiza um menor número de leituras e escritas e

a implementação que apenas usa sub-chunking realiza mais leituras e escritas que o algoritmo original.

Contudo, verifica-se que o uso conjunto das duas implementações implica um número de leituras e

escritas inicialmente próximo do da implementação original mas, à medida que aumenta a cardinalidade

das dimensões, passa a realizar um maior número destas operações quando comparada com a

implementação original ou a que utiliza apenas sub-treeing.

Estes resultados levantam a questão de qual a verdadeira utilidade destas optimizações, se na prática

conduzem à realização de um maior número de operações de leitura e escrita e , consequentemente, a

maiores tempos de execução do algoritmo. O gráfico abaixo responde a esta questão, ao mostrar que a

partir de um determinado volume de dados (2 560 000 tuplos com 4 dimensões) o algoritmo original não

consegue efectuar o cálculo do agregado. Esta situação verificava-se igualmente na implementação de

Tam [Tam1998], que não conseguia completar os cálculos para volumes de dados superiores a 240000

tuplos com 6 dimensões.

Figura 37 – Tempo consumido no cálculo do agregado pelas diferentes implementações para 2560000 tuplos

Como se pode observar, o algoritmo original e a implementação que apenas emprega sub-treeing

apresentam um tempo de cálculo igual a 0, o que na prática significa que não conseguiram efectuar o

cálculo por falta de memória. Apenas as implementações que realizam sub-chunking conseguiram

computar o agregado com sucesso, apresentando a implementação que emprega ambas as

optimizações um desempenho melhor. Com efeito, foi esta a razão pela qual foram desenvolvidas e

introduzidas as optimizações referidas: apesar de não contribuirem para o desempenho do algoritmo

quando comparado com a sua versão original, são decisivas no sentido em que permitem efectuar

cálculos em situações em que o algoritmo original não consegue responder.

00:00:00

00:02:53

00:05:46

00:08:38

00:11:31

00:14:24

00:17:17

00:20:10

00:23:02

MW MW+ST MW+SC MW+SC+ST

Page 62: Algoritmos para a Geração de Hipercubos

61

Por fim, o gráfico da figura 38 mostra o efeito da variação da cardinalidade das dimensões no tempo de

cálculo do cubo. Para qualquer uma das implementações, a tendência é para um crescimento

exponencial do tempo utilizado para calcular o cubo. Essa tendência é mais clara para a implementação

original quando comparada com a implementação que apenas emprega sub-chunking.

Figura 38 – Efeito da variação da cardinalidade das dimensões no tempo de cálculo do cubo

Os tempos de execução para esta implementação do algoritmo são afectados pelo facto de ser

necessário diminuir o tamanho do sub-chunk à medida que aumenta o volume de dados, o que acarreta

a realização de um maior número de leituras e escritas e se reflecte na forma mais ―acidentada‖ da

curva. Esta causalidade é comprovada pelos gráficos das figuras 39 e 40.

Figura 39- Comparação entre as leituras realizadas para diferentes cardinalidades de dimensões

00:00:00

00:00:43

00:01:26

00:02:10

00:02:53

00:03:36

00:04:19

T8 T9 T10 T11 T12 T13 T14 T15 T16

MW

MW+ST

0

100000

200000

300000

400000

500000

600000

700000

800000

T8 T9 T10 T11 T12 T13 T14 T15 T16

Leituras

MW

MW+ST

MW+SC

MW+SC+ST

Page 63: Algoritmos para a Geração de Hipercubos

62

Figura 40 – Comparação entre as escritas realizadas para diferentes cardinalidades de dimensões

0

20000

40000

60000

80000

100000

120000

T8 T9 T10 T11 T12 T13 T14 T15 T16

Escritas

MW

MW+ST

MW+SC

MW+SC+ST

Page 64: Algoritmos para a Geração de Hipercubos

63

5 Balanço final

O objectivo do presente trabalho consistiu em realizar um estudo detalhado do algoritmo Multi-Way,

assim como das optimizações propostas por forma a que este pudesse ser aplicado com sucesso a

grandes volumes de dados, o que não era possível com a sua implementação tal como proposto.

Infelizmente, não foi possível ter acesso a outras implementações como forma de estabelecer mais

comparações, estando apenas disponíveis o artigo de proposta do algoritmo Multi-Way [Zhao1997] e o

relatório do trabalho realizado por Tam [Tam1998], no qual é descrita uma variante do algoritmo

disponibilizado no sistema DBMiner. Como tal, optou-se por implementar o algoritmo original e,

adicionalmente, duas optimizações no sentido de fazer com que o algoritmo pudesse computar cubos a

partir de grandes volumes de dados. As optimizações propostas foram as seguintes:

A optimização designada como sub-treeing, que está relacionada com a estrutura de dados

básica do algoritmo (MMST) e que permite que o algoritmo explore um número menor de nós, o

que provoca um acréscimo no desempenho do mesmo

A optimização designada como sub-chunking, que altera ligeiramente uma das estratégias

adoptadas pelo algoritmo para gerir o tamanho dos arrays de forma a que seja sempre

aplicável, independentemente da dimensão dos dados e da memória existente. Porém, como

consequência desta optimização, o algoritmo necessita de realizar operações de leitura e

escritas adicionais sobre a base de dados, o que resulta num decréscimo do desempenho.

Assim, verifica-se que apesar da aplicação conjunta das duas optimizações não aumentar o

desempenho do algoritmo, a sua aplicação tem um impacto decisivo a nível do seu potencial. Isto deve-

se fundamentalmente ao facto de que as optimizações propostas tornam possível a execução do

algoritmo em situações nas quais, tanto a sua implementação original como a variante proposta por Tam,

não conseguem obter resultados por falta de memória.

Page 65: Algoritmos para a Geração de Hipercubos

64

6 Referências

[Agrawal1994] Agrawal, Rakesh; Ramakrishnam Srikant. ―Fast Algorithms for Mining Association Rules.‖

Proceedings of the 20th International Conference on VLDB. Santiago, 1994

[Agrawal1996] Agrawal, Sameet, et al. ―On The Computation of Multidimensional Aggregates.‖

Proceeddings of the 22nd VLDB Conference, pp. 506-521, 1996

[Beyer1999] Beyer, Kevin; Raghu Ramakrishnam. ―Bottom-Up Computation of Sparse and Iceberg

CUBEs.‖ Proceedings of ACM SIGMOD, 1999

[Chauduri1997] Chanduri, Surajit; Umeshwar Dayal. ―An Overview of Data Warehousing and OLAP

Technology.‖ ACM SIGMOD Record 26, n.º 1, pp. 65-74, 1997

[Gray1997] Gray, Jim, Surajit Chaduri, Adam Bosworth, Andrew Layman, Don Reichart; Murali

Venkatrao. ―Data Cube: A Relational Aggregation Operator Generalizing Group-By, Cross-Tab and Sub-

Totals.‖ Journal of Data Mining and Knowledge Discovery 1, n.º 1, pp. 29—53, 1997

[Han1999] Han, Jiawei, Jian Pei, e Yiwen Yin. ―Mining Frequent Patterns Without Candidate Generation.‖

Technical Report TR-99-12, Department of Computer Science, Simon Fraser University, 1999

[Han2001a] Han, Jiawei; Micheline Kamber. Data Mining: Concepts and Techniques. Morgan Kaufmann,

2001

[Han2001b] Han, Jiawei, Jian Pei, Guozhu Dong, e Ke Wang. ―Efficient Computation of Iceberg Cubes

With Complex Measures.‖ Proceedings of the International Conference on Management of Data, 2001

[Harinarayan1996] Harinarayan, Venkv; Anand Rajaraman; Jeffrey D. Ullman. ―Implementing Data Cubes

Efficiently‖ Proceedings of ACM-SIGMOD International Conference on Management of Data, Montréal,

pp. 205—216, 1996

[Inmon1996] Inmon, W. H.; ―Building the Data Warehouse‖, John Wiley & Sons, New York, 1996

[Ross1997] Ross, Kenneth A.; Divesh Srivastava. ―Fast Computation of Sparse Datacubes‖. Proceedings

of 23rd VLDB Conference, Atenas, pp. 116—125, 1997

[Tam1998] Tam, Yin Jenny. ―Datacube: Its Implementation and Application in OLAP Mining.‖ MSC tese,

Simon Fraser University, 1998

[Xin 2003] Xin, Dong; Jiawei Han; Xiao Lei Li; Benjamin W. Wah. ―Star-Cubing: Computing Iceberg

Cubes by Top-Down and Bottom-Up Integration‖ Berlim, 2003

Page 66: Algoritmos para a Geração de Hipercubos

65

[Zhao1997] Zhao, Yihong; Prasad M. Deshpande; Jeffrey F. Naughton. ―An Array Based Algorithm for

Simultaneous Multidimensional Aggregates‖. Proceedings of ACM-SIGMOD International Conference on

Management of Data, Tucson, pp. 159—170, 1997