Bases de Dados Remoções em árvores B + Remoção em árvores B + Remoção procurar o registo e removê-lo do ficheiro se o apontador ou contentor ficar vazio, remover a entrada (valor, apontador) da folha se a folha ficou abaixo do mínimo de (n-1)/2 valores se for possível, passar estes valores para o nó da esquerda, remover a folha, e remover a entrada respectiva no nó ascendente se isso não for possível, redistribuir os apontadores pelos nós vizinhos e ajustar o valor da chave no nó ascendente 2 1
Remoção em árvores B + Se ao modificar o nó ascendente, este ficar com um número de apontadores abaixo de n/2 repetir o procedimento recursivamente Estes efeitos "sobem" pela árvore até chegar a um nó que fique com pelo menos n/2 apontadores Se a raiz ficar só com um descendente depois da remoção, então o descendente passa a ser a nova raiz 3 Remoção em árvores B + exemplo 1 4 2
Remoção em árvores B + exemplo 2 5 Remoção em árvores B + exemplo 3 6 3
Remoção em árvores B + exemplo 3 Neste exemplo a sequência da remoção é a seguinte: 1. desaparece uma folha 2. no nó ascendente, desaparece o apontador para essa folha 3. pela propriedade p (C) o nó ascendente fica abaixo do limite de n/2 apontadores, logo é necessário redistribuir 4. só há um nó vizinho à esquerda, redistribuir com esse 5. só são necessários 4 apontadores (porque só há 4 folhas), logo ficam 2 apontadores em cada nó 6. se ficam 2 apontadores, fica apenas 1 valor em cada nó 7. pela propriedade (B) o valor que fica em cada um desses nós é o menor valor da sub-árvore direita 8. depois de mexer no 2º nível é necessário verificar a coerência do nó ascendente (raiz) 9. pela propriedade (B) o valor que fica na raiz é o menor valor da sub-árvore direita, ou seja, Mianus 7 Bases de Dados Índices do tipo hash 4
Hashing estático Um contentor armazena um conjunto de registos tipicamente um contentor ocupa um bloco em disco Ficheiros com organização do tipo hash função de hash determina contentor de um registo recebe como parâmetro o valor da chave de procura e devolve um apontador para o contentor Num mesmo contentor t pode haver registos com diferentes valores de chave de procura os contentores são pesquisados sequencialmente 9 Hashing estático exemplo 10 5
Funções de hash A função de hash ideal devia ser uniforme todos os contentores ficam com o mesmo número de valores de chave de procura devia ser aleatória todos os contentores ficam com o mesmo número de registos Tipicamente, as funções de hash trabalham com a representação binária do valor da chave de procura p.ex. somar todos os caracteres da string e fazer o resto da divisão pelo número de contentores 11 Overflow de contentores Pode ocorrer overflow de contentores devido a número insuficiente de contentores desequilíbrio na distribuição dos registos múltiplos registos com a mesma chave de procura função de hash não uniforme A probabilidade de overflow de um contentor não pode ser eliminada é normalmente resolvida com contentores extra (overflow buckets) 12 6
Overflow de contentores Encadeamento de contentores 13 Índices do tipo hash Pode ser usado hashing para organização de ficheiros e para criação de índices os índices do tipo hash são normalmente usados como índices secundários 14 7
Índices do tipo hash exemplo 15 Problemas na utilização de hashing estático A função de hash mapeia valores da chave de procura para um número fixo de contentores se a BD crescer, desempenho sofre com excesso de contentores extra mesmo que o tamanho possa ser previsto, desperdício de espaço inicialmente se a BD diminuir, espaço desperdiçado reorganização periódica é dispendiosa Solução: fazer variar o número de contentores dinamicamente 16 8
Hashing dinâmico Permite modificar a função de hash dinamicamente Hashing extensível a função de hash gera valores numa gama alargada tipicamente inteiros com 32 bits a ideia é usar em cada momento apenas um prefixo para endereçar um conjunto de contentores seja i o comprimento do prefixo, com 0 i 32 número máximo de contentores endereçáveis: 2 i o valor de i varia conforme o tamanho da BD 17 Hashing dinâmico exemplo comprimento do prefixo ( i ) comprimento do prefixo para cada contentor ( i j i ) 18 9
Hashing dinâmico procura O prefixo com i bits permite localizar a entrada correcta no índice mas o mesmo contentor pode ser usado em várias entradas significa que o prefixo do contentor é i Para encontrar o contentor com chave K j 1. calcular funcao_hash(k j ) = X 2. usar os primeiros i bits de X para localizar a entrada no índice 3. seguir o apontador respectivo para o contentor 19 Hashing dinâmico inserção Para inserir um registo com chave K j encontrar o contentor para essa chave se houver espaço no contentor, inserir o registo senão, separar o contentor em 2 e redistribuir os registos eventualmente será necessário aumentar i 20 10
Hashing dinâmico inserção (caso i j = i ) Como separar em 2 um contentor para a chave K j se i j = i (só há um apontador para o contentor j ) incrementar o valor de i, o que duplica o tamanho do índice substituir cada entrada no índice por 2 entradas que apontam para o mesmo contentor alocar novo contentor z e fazer i j = i z = i colocar o segundo apontador de j a apontar para z remover e re-inserir cada registo em j (agora com novo i j ) alguns registos vão parar a j, outros a z inserir o novo registo com chave K j 21 Hashing dinâmico inserção (caso i j < i ) Como separar em 2 um contentor para a chave K j se i j < i (mais do que um apontador para j ) alocar novo contentor z e fazer i j = i z = i j + 1 a segunda metade das entradas que apontam para j passam a apontar para z remover e re-inserir cada registo em j (agora com novo i j ) alguns registos vão parar a j, outros a z inserir o novo registo com chave K j se o contentor t ainda estiver cheio, repetir recursivamente um dos casos i j = i ou i j < i, como apropriado se o contentor permanecer cheio, usar um contentor extra (i atingiu o máximo e há overflow) 22 11
Hashing dinâmico inserção 23 Hashing dinâmico inserção 24 12
Hashing dinâmico inserção 25 Hashing dinâmico inserção 26 13
Hashing dinâmico inserção 27 Hashing dinâmico remoção Para apagar um valor de chave localizar o registo dentro do seu contentor e removê-lo se o contentor ficar vazio, removê-lo e actualizar o índice é possível juntar contentores que tenham o mesmo número i j e o mesmo prefixo nos primeiros i j -1 bits é possível diminuir o tamanho do índice operação dispendiosa, só feita quando o número de contentores é muito menor que o número de entradas no índice 28 14
Bases de Dados Índices e SQL Definição de índices em SQL Criação de um índice create index index_name on relation_name ( attribute_list ) p.ex. create index branch_index on branch(branch_name) é possível escolher o tipo de índice com using type Usa-se create unique index para dizer que a chave de procura é chave candidata da relação falha se os atributos dados não forem chave primária Para eliminar um índice drop index index_name on relation_name 30 15
Índices com múltiplas chaves de procura Certas perguntas exigem múltiplos índices select account_number from account where branch_name = Perryridge and balance = 1000 estratégias possíveis usar índice para branch_ name e testar valor de balance usar índice para balance e testar valor de branch_name usar índice para branch_name e outro para balance e intersectar os resultados 31 Chaves de procura compostas Chaves de procura compostas chaves de procura com mais de um atributo p.ex. (branch_name, balance) Ordem lexicográfica (a 1, a 2 ) < (b 1, b 2 ) se (a 1 < b 1 ) ou (a 1 = b 1 )e(a 2 <b) 2 32 16
Chaves de procura compostas where branch_name = "Perryridge" and balance = 1000 O mesmo índice pode ser usado para obter os registos que satisfazem as duas condições mais eficiente que usar índices separados também é eficiente noutros casos where branch_name = "Perryridge" and balance < 1000 não é eficiente em where branch_name < "Perryridge" and balance = 1000 obtém registos que satisfazem a primeira mas não a segunda condição 33 17