Baixe o app para aproveitar ainda mais
Prévia do material em texto
BANCO DE DADOS II Representação de Dados Versão dos Slides: 0.773 Prof. Dr.-Ing. Leonardo Andrade Ribeiro DCC-UFLA, Lavras Prof. Dr.-Ing. Leonardo Andrade Ribeiro Agenda Introdução Campos de Tamanho Fixo Registros de Tamanho Fixo Registros e Campos de Tamanho Variável Blocos Ponteiros para Blocos e Registros Campos Volumosos Modificação de Registros 2 3 armazenamento externo serviços de arquivos controle de propagação estruturas de armazenamento caminhos de acessos lógicos estruturas de dados lógicas C5 C4 C3 C2 C1 Camada 3: Estruturas de Armazenamento 4 armazenamento externo serviços de arquivos controle de propagação estruturas de armazenamento caminhos de acessos lógicos estruturas de dados lógicas interface de registros internos armazenamento de registros (na B*-tree) unidades de endereçamento: registros intern., B*-trees, tabelas hash estruturas auxiliares: índices de páginas, tabelas de endereços unidades de endereçamento: páginas, segmentos C5 C4 C3 C2 C1 Camada 3: Estruturas de Armazenamento 5 Atributos Tuplas Relações Silva ˽ Campos Registros Arquivos Sobrenome Silva Sobrenome Silva Nome Jõao Endereço Rua Brasil Jõao ˽ Silva ˽ Rua Brasil ˽ Sobrenome Silva Nome Jõao Endereço Rua Brasil Sobrenome Silva Nome Jõao Endereço Rua Brasil ... ... ... ... Blocos ... ... ... Representação Lógica Representação Física Representação de Dados Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representação de Elementos de Dados Considere a expressão SQL abaixo: CREATE TABLE Aluno ( nome CHAR(30) PRIMARY KEY, endereço VARCHAR(255), genero CHAR(1), aniversário DATE, foto BLOB, ); No contexto da expressão DDL acima, várias questões surgem 6 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representação de Elementos de Dados 1. Como representar tipos de dados SQL como campos? 2. Como representar tuplas como registros? 3. Como representar coleções de registros em blocos? 4. Como representar e armazenar relações como arquivos? 7 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representando Elementos de Dados Básicos SQL 5. Como lidar com tamanhos variáveis de registros que fazem com que blocos não sejam divididos de maneira uniforme? 6. O que acontece quando o tamanho de um registro muda porque algum campo foi atualizado? Como é gerenciado do espaço em um bloco, principalmente quando registros aumentam de tamanho 7. Como armazenas grandes elementos de dados como fotos e vídeos (tipo de dadas BLOB, Binary Large Object) 8 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Agenda Introdução Campos de Tamanho Fixo Registros de Tamanho Fixo Registros e Campos de Tamanho Variável Blocos Ponteiros para Blocos e Registros Campos Volumosos Modificação de Registros 9 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representação de Campos de Tamanho Fixo De maneira geral, todos os tipos de dados são representados como campos consistindo em sequências de bytes; • Estas sequências são agrupadas para formar registros Podemos ter campos de tamanho fixo ou variável • Campos de tamanho variável resultam em registros de tamanho variável Campos e registros de tamanho fixo são simples de implementar e serã discutidos a seguir 10 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representanto Tipos Númericos Exemplos de Tipos númericos em SQL: • INTEGER: 2 ou 4 bytes • FLOAT: 4 ou 8 bytes Tipos numéricos são representados por campos contendo strings de bits de tamanho fixo • Estas strings de bits são interpretados diretamente pelo hardware para a realização de operações aritméticas básicas 11 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representando Strings de Tamanho Fixo String de tamanho fixo são descritas pelo tipo SQL CHAR(𝑛) • Declara strings cujo de tamanho fixo de 𝑛 caracteres O campo para um atributo deste tipo é um array de 𝑛 bytes Caso o valor do atributo seja uma string de tamanho menor que 𝑛, então o array é completado com um caracter especial (que iremos denotar por ‘˽‘) Exemplo: Consider um atributo do tipo CHAR(8) e uma tupla cujo valor correspondente a este atributo é ‘Silva‘. O valor do array de bytes será: S i l v a ˽ ˽ ˽ 12 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representando Strings de Tamanho Variável O tipo SQL VARCHAR(𝑛) é frequentemente usado para representar string de caracteres cujo tamanho apresenta grande variação Entretanto, é comum implementar atributos do tipo VARCHAR(𝑛) alocando um array de tamanho fixo de 𝑛 + 1, independentemente do tamanho real da string a ser armazenada Neste caso, representações de strings VARCHAR precisam identificar o final da string no array de bytes. Duas técnicas são populares: • Tamanho + conteúdo: O(s) primeiro(s) byte(s) do array de tamanho 𝑛 + 1 é usado para representar o tamanho da string. Ex.: 5 S i l v a • String terminada com null: um caratecter especial é usado para identificar o final da string. Ex.: S i l v a ˽ 13 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representado Outros Elementos de Dados O tipo DATE pode ser representado da mesma maneira que strings de tamanho fixo O tipo TIME pode incluir frações de segundo e neste caso ser representado como VARCHAR ou em campos de tamanho realmente variável O tipo SQL BIT(𝑛) – uma sequência de bits de tamanho 𝑛 – pode ser representado por uma sequência de 𝑛/8 bytes; caso o valor de 𝑛 não seja múltiplo de 8, os bits não-usados do último byte são simplesmente ignorados 14 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Agenda Introdução Campos de Tamanho Fixo Registros de Tamanho Fixo Registros e Campos de Tamanho Variável Blocos Ponteiros para Blocos e Registros Campos Volumosos Modificação de Registros 15 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Registros de Tamanho Fixo Registros de tamanho fixo são compostos por campos de tamanho fixo Exemplo: Considere a declaração da relação Aluno vista anteriormente (apenas desconsidere o attributo ‘foto‘). Temos os seguintes campos: 1. nome, uma string de caracteres de 30 bytes 2. endereço, do tipo VARCHAR(255), é representado por 256 bytes (𝑛 + 1 bytes) 3. genero, um único byte (caracter ‘F‘ ou ‘M‘) 4. aniversario, do tipo DATE. Vamos assumir que são usados 10 bytes para a representação de datas 16 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Registros de Tamanho Fixo: Exemplo 17 nome end. gen aniver. 0 30 286 287 297 Temos que registros do tipo Aluno ocupam 30 + 255 + 1 + 10 = 296 bytes Offset: “distância” medida em bytes entre o início do registro e o primeiro byte do campo offset Prof. Dr.-Ing. Leonardo Andrade Ribeiro Armazenamento no Disco e Posição na Memória Algumas máquinas realizam operações de leitura e escrita de maneira mais eficiente quando os dados são posicionados em bytes da memória principal que são múltiplos de 4 (arquitetura de 32 bits) ou 8 (64 bits) • Certos tipos de dados como inteiros devem necessariamente começar em endereços de memória que são múltiplos de 4 Este fato tem influência na maneiraque dados são armazenados em disco • Para evitar operações de realinhamento quando dados são lidos do disco para memória, tamanho de blocos e posições de campos em registros devem ser ajustados 18 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Armazenamento no Disco e Posição na Memória Vamos considerar arquiteturas de 32 bits (múltiplos de 4) a) O primeiro byte de um bloco devem começar em um endereço múltiplo de 4 • Blocos com tamanho igual a uma potência de 2. Ex.: 32Kb = 32768 = 215 b) Todos os campos em um registro devem começar em um offset do ínicio do registro que é múltiplo de 4 19 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Armazenamento no Disco e Posição na Memória 20 0 nome end. gen aniver. 30 286 287 297 offset nome end. gen aniver. 0 32 288 292 304 offset Ajustando offsets de campos para múltiplos de 4 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Cabeçalhos de Registros Além dos dados em si, registros podem armazenar metadados; estes metadados constituem o cabeçalho do registro Informações tipicamente armazenadas no cabeçalho: 1. Ponteiro para o local no catálogo onde está armazenado o esquema de relação ao qual este registro está associado 2. Tamanho do registro − Necessário para registros de tamanho variável; para registros de tamanho fixo, esta informação permite acessar o bloco seguinte rapidamente 3. Timestamps indicando a data e horário da última modificação ou do último acesso ao registro 21 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Esquema de Registros No geral, cada tipo de registro usado em um sistema de banco de dados possui um esquema que é armazenado no catálogo do SGBD O esquema inclui os nomes e os tipos de dados dos campos do registro e também os offsets dentro do registro O esquema é consultado quando é necessário acessar informações sobre o registro 22 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Esquema dos Registros Acesso ao esquema do registro é necessário mesmo para registros de tamanho fixo Os principais motivos são: • Atualizações estruturais dos dados (e.g., inserção de um novo campo no esquema de uma relação): consultas precisam ter acesso ao esquema atual de registro • A localização do registro no sistema de armazenamento não é suficiente para inferir o esquema de relação ao qual o registro está associado. Ex.: tuplas de diferentes relações podem estar armazenadas em um mesmo bloco 23 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Cabeçalhos de Registros 24 nome end. gen aniver. 0 12 44 300 304 offset ponteiro p esquema tamanho timestamp 316 Cabeçalho: Bytes relativos aos offsets 0-11 • Bytes 0-3: ponteiro (offset de uma área do catálogo) para o esquema • Bytes 4-7: tamanho representado por um inteiro de 4 bytes • Bytes 8-11: timestamp respresentado por um inteiro de 4 bytes Prof. Dr.-Ing. Leonardo Andrade Ribeiro Agenda Introdução Campos de Tamanho Fixo Registros de Tamanho Fixo Registros e Campos de Tamanho Variável Blocos Ponteiros para Blocos e Registros Campos Volumosos Modificação de Registros 25 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Campos e Registros de Tamanho Variável Campos e, consequentemente, registros podem ter tamanho variável Certos tipos de dados possuem tamanho inerentemente variável: • No exemplo anterior, o campo endereço pode ocupar até 255 bytes. Na prática, a grande parte dos endereços podem ser armazenados em bem menos que 255 bytes 26 Campos e Registros de Tamanho Variável Registros podem possuir campos de tamanho fixo e campos de tamanho variável Uma estratégia comum é armazenar todos registros de tamanho fixo antes que os registros de tamanho variável • Se um campo de tamanho variável é armazenado primeiro, então o offset de todos campo de tamanho fixo seguintes não poderá mais ser inferido pela sua posição e tamanho Para permitir que qualquer campo possa ser acessado diretamente em um registro, o cabeçalho é estendido com ponteiros para os campos de tamanho variável 27 Prof. Dr.-Ing. Leonardo Andrade Ribeiro gen aniver. nome endereço Campos e Registros de Tamanho Variável Obs.: Se ordem dos campos é a mesma para todos os registros, então não é necessário armazenar um ponteiro para o primeiro campo de tamanho variável 28 outras informações do cabeçalho tamanho reg. pont. para endereço Campos de tamanho fixo Campos de tamanho variável Prof. Dr.-Ing. Leonardo Andrade Ribeiro Representando Valores NULL Tuplas possuem possuem frequentemente atributos cujo valor é NULL Valores NULL não precisam ser armazenados diretamente • Economia de espaço Estratégia para armazenamento de campos de tamanho variável é bastante conveniente para lidar com valores NULL: • Sempre que o valor de um campo for NULL, basta colocar um ponteiro para null no lugar do offset do campo dentro do registro 29 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Agenda Introdução Campos de Tamanho Fixo Registros de Tamanho Fixo Registros e Campos de Tamanho Variável Blocos Ponteiros para Blocos e Registros Campos Volumosos Modificação de Registros 30 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Armazenamento de Registros em Blocos Blocos são a unidade de transferência entre o disco e a camada C1 de um SGBD (serviços de arquivos) e entre C1 e C2 (controle de propagação) Para acessar um tupla de uma relação, o bloco completo é movido para a memória Assim como registros, o layout físico de blocos também contém metadados armazenados no cabeçalho 31 Cabeçalhos de Blocos Informações armazenadas no cabeçalho: • Links para outros blocos que fazem parte da mesma “rede” de blocos (Uma rede de blocos é usada na criação de índices e será estudada mais adiante no curso.) • Informação sobre o papel desempenhado por este bloco nesta rede de blocos • Informações sobre as relações cujas tuplas estão armazenadas neste bloco • O identificador do bloco • Timestamp (data e horário do último acesso e/ou atualização) • Ponteiro para um bloco de overflow (mais adiante) • Uma “tabela de offsets” 32 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Tabela de Offsets Todo registro armazenado em um bloco possui uma entrada nesta tabela armazenando seu offset no bloco • Neste contexto, offset representa a distância medida em byte entre o ínicio do bloco e o primeiro byte do registro Usando a tabela de offsets facilita a execução de operações de modificação de registros • Movimentação de registros dentro e entre blocos e deleção (veja operações de atualização mais adiante) 33 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Layout Físico de Blocos Notem que a tabela “cresce” do ínicio para o final do bloco, ao passo que os registros são armazenados a partir do final do bloco • Estratégia necessária quando temos registros de tamanho variável e, portanto, não é possível saber previamente a quantidade de registros que serão armazenados no bloco 34 reg. n ... reg.2 reg. 1 768 3584 3840 cabeçalho Tabela de offsets 3840 3584 768 ... 1 2 n espaço não usado Prof. Dr.-Ing. Leonardo Andrade Ribeiro Agenda Introdução Campos de Tamanho Fixo Registros de Tamanho Fixo Registros e Campos de Tamanho Variável Blocos Ponteiros para Blocos e Registros Campos Volumosos Modificação de Registros 35 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Acessando Endereços de Blocos e Registros Como já mencionado anteriormente, o BD é dividido logicamente em blocos em C1 e em páginas na camada C2 • Tipicamente, blocos e páginas possuem o mesmo tamanho e o mesmo identificador • Notação: 𝑃𝑖 (𝐵𝑖) = Página (bloco) cujo identificador é 𝑖 36 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Espaço de endereçamento do SGBD O espaço de endereçamento do SGBD é composto por endereços lógicos e físicos • Endereços lógicos: corresponde aos identificadores de blocos (ou páginas) • Endereços físicos: contém informações para acessar o bloco no dispositivo de armazenamento como canais, trilhas, cilindros, endereços IPs, etc 37 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Tabela de Mapeamento Cada endereço lógico é associado com um endereço físico através de uma tabela de mapeamento Localizada e administrada em C1 38 endereço lógico 𝐵𝑖 ip: 192.168.0.1 canal: 2 disco:0 cilindro: 13 setor: 42 endereço físico tabela de mapeamento Tabela de Tradução Uma segunda tabela, localizada e administrada em C2 e chamada tabela de tradução, é usada para idenficar blocos que se encontram em memória, isto é, em quadros de página do buffer Para os blocos que se encontram em memória, a tabela de tradução também é usada para associar endereços lógicos do espaço de endereçamento do SGBD com endereços de memória do espaço de endereçamento do sistema operacional A operação inversa também pode ser realizada: dada um endereço de memória, encontre o endereço lógico correspondente Buffer do SGBD 𝑃13 0xFFA8C313 𝑃42 0x238D42BA 𝑃13 𝑃42 … … … … … … ... ... ... ... ... Tabela de Tradução Prof. Dr.-Ing. Leonardo Andrade Ribeiro Record Identifier (RID) RID: usado para como endereço de um registro Composto pelo identificador da página e a entrada na tabela de offsets 40 registro 13 offset=200 tabela de offsets 2 200 ... ... RID=42+2 Registro 13 𝑃42 página entrada na tabela Prof. Dr.-Ing. Leonardo Andrade Ribeiro Identificadores e Ponteiros Identificadores de páginas e RIDs podem ser interpretados como ponteiros no espaço de endereçamento do SGBD • Identificadores de páginas podem ser usados em estruturas como árvores B para ligar um nó pai com um nó filho • Um atributo de um registros pode conter um RID para apontar para outro registro 41 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Swizzling de Ponteiros Ponteiros do SGBD não podem ser usados diretamente: é necessário substituir o identificador da página pelo endereço de memória do quadro de página correspondente Esta operação é denominada swizzling de ponteiros: conversão de um ponteiro no espaço de endereçamento do SGBD em um ponteiro válido no espaço de endereçamento do SO Operação realizadas pela camada C2 (gerenciador de buffer); pode requer acesso à camada C1 se a página apontada não estiver em memória 42 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Swizzling de Ponteiros: Exemplo 43 RID = 42 + 2 id. da página Operação de swizzling entrada na tabela de offsets 0x238D42BA + 2 Endereço de memória do SO Prof. Dr.-Ing. Leonardo Andrade Ribeiro Estratégias para Swizzling de Ponteiros Existem várias estratégias para realização do swizzling de ponteiros • Imediato: quando um bloco é carregado para memória, a operação de swizzling é realizada sobre todos ponteiros presentes nos registros deste bloco • Imediato com restrição: a operação de swizzling é realizada apenas sobre ponteiros para páginas que já se encontram em memória • Sob demanda: a operação de swizzling é realizada apenas quando a página correspondente tem que ser acessado 44 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Unswizzling de Ponteiros Quando uma página é propagada para o disco é necessário realizar a operação inversa: todos os ponteiros que contém endereços de memória devem ser substituídos pelo endereço lógico correspondente Para isso, a tabela de tradução deve conter, além do endereço de memória de um bloco, uma lista de todos páginas em memória que contém ponteiros para esta página propagada 45 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Agenda Introdução Campos de Tamanho Fixo Registros de Tamanho Fixo Registros e Campos de Tamanho Variável Blocos Ponteiros para Blocos e Registros Campos Volumosos Modificação de Registros 46 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Campos Volumosos SGBDs modernos suportam atributos cujos valores são itens de dados volumosos • Ex.: VITA (Video, Image, Text, and Audio) Principais consequências: • Armazenamento de todo o conteúdo de um registro em um mesmo bloco pode causar grande desperdício de espaço • Registros podem possuir tamanho maior que um bloco • Necessidade de técnicas especiais de armazenamento 47 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Registros Estendidos (Spanned Records) Considere registros cujo tamanho é pouco maior que a metade de um bloco Armazenamento destes registros em um mesmo bloco resulta em aproximadamente 50% de desperdício Registros estendidos: registros que se estendem por mais de um bloco • A porção de um registro estendido que aparece em um único bloco é chamada de fragmento do registro 48 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Registros Estendidos Registros estendidos requerem informação extra no cabeçalho: 1. Cada registro ou fragmento de registro deve conter um bit indicando se o registro é ou não extendido 2. Se o registro é um fragmento, então é necessário bits informando se o fragmento é o primeiro ou o último fragmento do registro 3. Quando for o caso, é necessário armazenar ponteiros para o fragmento anterior e/ou para o fragmento posterior 49 Prof. Dr.-Ing. Leonardo Andrade Ribeiro BLOBS (Binary, Large Objects) Campos armazenando informações do tipo VITA podem ser bem maiores que um bloco (tamanho em MBs ou GBs) No contexto de SGBDs, os valores destes campos são representados como BLOBS BLOBS não são armazenados juntamente com campos que armazenam valores comunsNecessidade de mecanismos especiais de armazenamento e acesso Um ponteiro no registro indica a real localização do valor BLOB 50 Prof. Dr.-Ing. Leonardo Andrade Ribeiro BLOBS BLOBS são armazenados como uma sequência de blocos Exploração (massiva) de técnicas para acelerar acesso ao disco • Organização por cilindros • Distribuição a nível de blocos BLOBs podem ser acessados incrementalmente. Ex.: Em vez de enviar um vídeo de 2GB de uma vez, envia- se um bloco por vez para o cliente, sob demanda Acesso a partes específicas: necessidade de índices especiais 51 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Agenda Introdução Campos de Tamanho Fixo Registros de Tamanho Fixo Registros e Campos de Tamanho Variável Blocos Ponteiros para Blocos e Registros Campos Volumosos Modificação de Registros 52 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Inserção de Novos Registros Quando os registros de uma relação não são mantidos em uma ordem em particular, a inserção de umnovo registro é simples: • Coloca-se o novo registro no espaço não-utilizado de um bloco • Se o bloco estiver cheio, cria-se um novo bloco e coloca-se o registro neste novo bloco 53 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Inserção de Novos Registros Cuidados especiais são necessários quando existe uma ordenação definida sobre os registros de um arquivo (representando uma tabela) • Exemplo: registros do arquivo Aluno são mantidos ordenados pelo valor do campo Nome Movimentação de registros dentro do bloco é necessária para manter ordenação Toda movimentação de registros requer atualização na tabela de offsets no cabeçalho do bloco Notem que o uso da tabela de offsets evita que ponteiros para registros que forem deslocados dentro de um bloca sejam “quebrados” • Ponteiro contém referência para entrada na tabela de offsets, não o offset em si 54 Blocos de Overflow Quando é necessário manter ordenação e não existe espaço suficiente no bloco para acomodar um novo registro, então um bloco de overflow tem que ser criado Todo bloco 𝐵 possui espaço no cabeçalho para um ponteiro para um bloco de overflow, onde registros que pertencem logicamente ao bloco 𝐵 • Um blocos de overflow pode possuir um ponteiro para um segundo bloco de overflow e assim por diante 55 Bloco B Bloco de overflow de B Blocos de Overflow Notem que, normalmente, um bloco de overflow será armazenado em posição distante ao bloco original Como resultado, teremos perda de performance em operações acessando sequência ordenada de registros • Cada acesso a um bloco de overflow resulta em um acesso randômico ao disco 56 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Deleção de Registros Deleção de registros envolvem atualização da tabela de offsets e movimentação de registros para manter espaço não ocupado concentrado em uma região específica do bloco • Caso exista um bloco de overflow, o mesmo pode ser deletado caso os registros restantes dos dois blocos couberem em um único bloco 57 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Deleção de Registros Como podem existir ponteiros externos para registros deletados, é necessário substituir o ponteiro correspondente na entrada na tabela de offsets por um ponteiro para null Notem que a entrada para um registro na tabela de offsets é permanente até que o BD seja reconstruído • Isto é, uma entrada deve ser mantida mesmo após o registro correspondente ser deletado 58 Prof. Dr.-Ing. Leonardo Andrade Ribeiro Atualização de Registros Para registros de tamanho fixo, atualizações não requerem ações especiais Registros de tamanho variável requerem cuidados similaires ao cuidados empregados no caso de inserção e deleção • Movimentação de registros em um bloco e criação/deleção de blocos de overflow 59
Compartilhar