• Nenhum resultado encontrado

Cache e seu Gerenciamento

3.4 Técnicas Auxiliares

Para um completo gerenciamento de cache dentro de um sistema, é necessário nos preocu- parmos com fatores além de substituição e atualização dos dados que estão armazenados.

Algumas técnicas auxiliares são de grande valor para um Gerenciador de Cache. Alguns sistemas de integração de dados – como o ACE-XQ – já possuem gerenciadores de cache com uma visão mais ampla, apresentando funcionalidades extras bastante interessantes. Uma delas é a técnica de Identificação de Subconsultas (conhecida como Query Containment), que também faz parte da proposta de melhoria do Gerenciador de Cache do sistema Integra, com algumas modificações. Esta técnica será descrita com mais detalhes a seguir.

3.4.1 Identificação de Subconsultas

Em sistemas de informação que utilizam cache é natural que, com a submissão de uma nova consulta, se busque dentro da cache uma consulta que case perfeitamente com a solicitada. Dessa forma, uma nova consulta só será respondida por uma que esteja na cache se ambas forem idênticas.

Consideremos uma situação em que o usuário submeteu a seguinte consulta, em SQL, ao sistema:

SELECT t i t u l o , a u t o r FROM l i v r o s

WHERE t i t u l o l i k e "% D a t a b a s e Cache%" AND ano > 2 0 0 5

Quando executada, ela retornará informações (titulo e autor) de todos os registros armaze- nados na tabela livros cujo campo título contenha o texto “Database Cache” e cujo ano seja maior que 2000.

Supondo que o sistema em questão possui uma cache e nela esteja armazenada apenas o resultado da seguinte consulta:

SELECT t i t u l o , a u t o r , ano , e d i t o r a FROM l i v r o s

WHERE t i t u l o l i k e "% Cache%" AND ano > 2 0 0 0

Ao receber a consulta submetida pelo usuário, um sistema com gerenciamento de cache convencional procuraria na cache uma consulta idêntica a que está sendo requisitada. Nesse exemplo, ele não encontraria uma consulta correspondente e ela deveria ser executada direta- mente na fonte de dados.

No entanto, podemos notar que a consulta que está na cache retorna os mesmos campos da primeira, além de informações adicionais, como ano e editora. Analisando ainda restrição desta consulta, constata-se que ela é mais abrangente que a primeira, visto que recupera to- dos os livros cujo título contenha a palavra “Cache” e o ano seja maior que 2000. Se essas duas consultas fossem executadas no mesmo banco de dados, ao mesmo tempo, o resultado da primeira corresponderia a um subconjunto do resultado da segunda, visto que esta é mais abrangente. Nesse caso, dizemos que a primeira consulta é uma subconsulta total da segunda, ou seja, a resposta da primeira está completamente contida na da segunda.

28

SELECT t i t u l o , a u t o r , p r e c o FROM l i v r o s

WHERE t i t u l o l i k e "% D a t a b a s e Cache%" AND ano > 2 0 0 5

Nota-se que a única diferença entre ela e a primeira é que agora ele busca mais uma infor- mação sobre o livro: o preço. Essa informação também não é retornada pela consulta que está na cache. No entanto, comparando a restrição das duas, notamos mais uma vez que a consulta da cache é mais abrangente que a que o usuário submeteu. O único problema é que o campo preco não está na consulta em cache. Nesse caso, dizemos que a consulta do usuário é uma subconsulta parcial da que está na cache, visto que esta contém parcialmente aquela.

Se o sistema for capaz de identificar na cache uma consulta que possa ser utilizada para responder – parcialmente ou totalmente – a do usuário, obviamente ele terá um maior aprovei- tamento de sua cache. Quando a consulta da cache contiver parcialmente a consulta do usuário, esta deve ser reformulada em duas: uma para ser executada sobre a consulta que está na cache e outra para ser executada na fonte.

Essa limitação em relação à busca de consultas em cache começou a ser discutida em [31], que sugeriu como melhoria a técnica de Identificação de Subconsultas entre consultas relaci- onais. Foi o primeiro passo nos estudos de uma técnica que virou tendência entre os sistemas que utilizam cache.

Identificar se uma consulta contém outra total ou parcialmente, ou seja, se um subconjunto dos dados que respondem uma consulta pode ser encontrado em outra, não é um trabalho trivial. No contexto relacional, esse problema já foi amplamente estudado ([32, 33, 34, 35]). Em [31] é provado que se trata de um problema NP-Completo. No entanto, os estudos para solução desse problema quando se tem consultas em XML ainda estão em fase bem inicial.

Recentemente, alguns pesquisadores iniciaram estudos sobre o problema de Identificação de Subconsultas para consultas em XPath [36, 37, 38, 39] e em XQuery [40, 41, 42]. Os dois problemas são bastante diferentes visto que as consultas em XPath retornam um conjunto de nós. Como o Integra trabalha com consultas em XQuery, focamos nossos estudos no escopo das consultas em XPath e XQuery, que possuem características semelhantes visto que XPath é um subconjunto de XQuery.

Em [43], os autores definem que uma consulta Q1 está contida em uma consulta Q2 deno- tado por Q1 v Q2 se, para qualquer banco de dados D, a resposta para Q1 corresponde a um subconjunto da resposta da consulta Q2. As duas consultas são ditas equivalentes, denotado por

Q1 ≡ Q2, se Q1 v Q2 e Q2 v Q1. Chandra e Merlin em [31] provam que para duas consultas conjuntivas Q1 e Q2, Q1 v Q2 se, e somente se, houver um mapeamento das variáveis de Q1 para as variáveis de Q2.

Identificação de Subconsultas e Reescrita de Consultas são assuntos já bem estudados para consultas conjuntivas em álgebras relacionais. No entanto, para consultas em XML, pesquisas sobre Identificação de Subconsultas ainda estão num estágio bastante imaturo.

Alguns procedimentos são comuns para identificação de Identificação de Subconsultas tanto em consultas em XQuery quanto em XPath: montagem das árvores representativas, nor- malização e minimização das consultas.

As técnicas de Identificação de Subconsultas para consultas em XQuery propostas, apesar de diversas, aparecem sempre agregadas a atividades em comum, como a normalização. Essa atividade será descrita na sessão a seguir.

3.4.1.1 Normalização

Da mesma forma que em SQL e em outras linguagens, em XQuery uma mesma consulta também pode ser formulada de várias formas. Isso se dá devido à vasta gama de funcionalidades que essas linguagens oferecem. A Figura 3.3 mostra três formas diferentes de se escrever uma mesma consulta em XQuery.

As diferenças entre as consultas podem ser simples, como entre a consulta A e a consulta B – que se diferenciam apenas pela ordem como estão dispostas as variáveis – ou mais complexas, como entre a consulta C e as outras – que se diferenciam pela estrutura. No entanto, todas elas retornam sempre os mesmos resultados quando executadas numa mesma base de dados.

Por conta dessa possibilidade de se escrever uma mesma consulta de várias formas diferen- tes, para que se possa realizar comparações para identificar se uma determinada consulta está na cache ou contida em outra que lá esteja, é necessário estabelecer um padrão de estrutura de consulta para facilitar as comparações.

A conversão de uma consulta formulada em uma determinada estrutura para a estrutura padrão consiste no processo chamado de Normalização.

Atualmente existem algumas técnicas de normalização de consultas definidas como em [17, 40, 44].

Em [40], os autores definem regras de normalização específicas para um grupo restrito de consultas que o sistema proposto trata. Em [17], estão definidas as regras de normalização adotadas pelo consórcio criador da linguagem XQuery, o W3C (World Wide Web Consortium).

30

Figura 3.3 Três maneiras de escrever uma mesma consulta em XQuery

Algumas regras são comuns a todas as técnicas de normalização encontradas. Por exemplo, na normalização de expressões do tipo FLWOR (expressões que contenham as cláusulas for, let, where, order by e return) o tratamento de cláusulas for mais complexas é feito da mesma forma. Essa regra determina que um for complexo deve ser reescrito como uma composição de várias expressões for mais simples. Aplicando essa regra em uma expressão do tipo:

FOR Var1in Exp1, Var2in Exp2, ... , Varnin Expnreturn Exp

obtém-se a seguinte expressão normalizada:

FOR Var1in Exp1return FOR Var2in Exp2return ... FOR Varnin Expnreturn Exp

onde Var1, Var2, ..., Varnsão variáveis e Exp1, Exp2, ..., Expnsão expressões.

Observando a regra, notamos que ela desmembra o FOR da expressão em vários outros FOR, para que cada um contemple apenas um par de variável e expressão.

Em [17], estão definidas as demais regras de normalização para diversos componentes dessa linguagem: • Literais; • Expressões Aritméticas; • Expressões Comparativas; • Expressões Lógicas; e • Expressões FLWOR.

Já em [40], os autores elaboraram um outro conjunto de regras de normalização – contendo inclusive a regra do FOR – para contemplar apenas um subconjunto de consultas em XQuery que o sistema por eles proposto atende.

3.4.1.2 Problemas relacionados

Ao identificar-se que uma consulta está contida em outra cujo resultado está armazenado na cache, para se obter o resultado daquela basta executá-la sobre o resultado da que já foi executada anteriormente. Teoricamente, a resposta será igual à resposta que seria dada se a consulta fosse executada diretamente na fonte de dados – considerando que a cache não esteja inconsistente com a fonte. No entanto, muitos dos algoritmos de Identificação de Subconsultas propostos nem sempre identificam com segurança se uma dada consulta está de fato contida e, portanto, pode ser respondida por outra. Eles apresentam falhas quanto à completude do resultado, ou seja, essas técnicas não garantem que o resultado obtido a partir da execução de uma consulta que está contida em outra na cache corresponda ao esperado.

Isso acontece com os algoritmos propostos em [40] e em [42]. As duas técnicas se baseiam no homomorfismo entre as árvores representativas de cada consulta com algumas condições de mapeamento adicionais para identificar se uma está contida na outra. Em [41], o homomorfismo entre árvores é assim definido:

Documentos relacionados