Organização de Arquivos e DadosOrganização, Estrutura e Operação de Arquivos
Estruturas de Arquivo Físicas vs. Lógicas
15 min de leitura · 6ª mais cobrada em Organização de Arquivos e Dados
Um arquivo é um conjunto de dados persistente sob um nome. Duas perguntas se misturam com facilidade: o que o programa enxerga e como esses dados ocupam o disco. A primeira é a estrutura lógica; a segunda, a estrutura física. O mesmo conteúdo pode ser uma fita de bytes, uma lista de registros ou uma árvore, e ainda assim ocupar o disco de jeitos diferentes.
O programa pede "o registro da matrícula ". Quem traduz isso para bloco — a unidade de transferência do disco — e deslocamento é a organização física. O método de acesso é uma terceira peça: a mesma organização admite varrer o próximo, pular para um endereço de bloco, ou recuperar pela chave. No sequencial restrito, recomeçar é rewind, não um salto para o início.
Campo, registro e arquivo
Um campo é o menor item nomeado: um inteiro de matrícula, um nome, um preço. Um registro é o agrupamento de campos que descreve uma entidade — um aluno, uma venda. O arquivo é a coleção desses registros ou, no caso mais pobre, só dos bytes.
Sem registro, o programa teria de saber sozinho onde termina o nome e começa a nota. O registro fixa essa fronteira: o campo é um atributo, o registro é a entidade, o arquivo é a coleção.
O setor, o cilindro e a trilha — a geometria do disco magnético — não fazem parte dessas definições. O programa quase nunca pensa nessa geometria; ele pede um registro. A organização física é quem calcula bloco e deslocamento.
Três visões lógicas
O mesmo conteúdo admite três organizações lógicas. São três jeitos de o programa — ou a biblioteca — interpretar o mesmo arquivo.
Sequência de bytes. O arquivo é um vetor de octetos, do deslocamento até . Não há registro embutido: quem interpreta o layout é o programa — um texto, um arquivo sem estrutura interna. O sistema de arquivos, a camada que persiste o nome e os bytes, só sabe ler, escrever e posicionar em deslocamentos.
Pedir "o terceiro aluno" não faz sentido para o sistema. Faz sentido "os bytes a partir de ", se o programa já tiver essa conta.
Sequência de registros. O arquivo é uma lista de registros. O registro pode ter tamanho fixo (todos com bytes; o -ésimo começa em ) ou tamanho variável (um campo de comprimento, ou um delimitador, antecede o próximo).
Em arquivo de registros o tamanho pode ser variável ou fixo. No variável, cada entrada é registro do mesmo jeito; muda só o endereço do sucessor. Quem trata o arquivo como registros — o sistema ou a biblioteca — já sabe onde um termina e o outro começa.
Árvore. Os registros — ou as páginas que os guardam — são nós com filhos. Caminhar pela chave escolhe um ramo. Essa visão dá escolha de ramo: dá para descer por um caminho sem varrer a fita. A sequência de bytes é a visão mais livre: o sistema não impõe layout.
O custo é o layout mais irregular. Por isso a árvore costuma usar registros de tamanho variável: cada nó carrega um número variável de chaves e ponteiros. Esse é o caso típico na prática, sem ser obrigatório. O que define a visão é a escolha de ramo.
A sequência de bytes é a mais flexível das três porque bytes só oferecem posição: quem interpreta o conteúdo é o programa. A fita de registros já impõe o próximo e, se os registros forem fixos, o -ésimo por aritmética. A árvore impõe escolha de ramo a cada nó: a chave decide o filho, e os irmãos do outro lado ficam de fora — acesso mais estruturado que a sequência de bytes.
Em tamanho fixo e variável, a diferença está no endereço do sucessor. Fixo: o endereço do registro é ; inserir no meio desloca tudo em múltiplos de . Variável: o sucessor só se conhece depois de ler o comprimento ou o delimitador; um registro maior que o buraco não cabe sem gravar noutro lugar ou reescrever.
O mapa físico
No disco, três arranjos clássicos respondem "onde está o registro da chave ". O arquivo direto é o nome clássico do arranjo hash: a chave passa por uma função e cai num balde, o conjunto de registros que compartilham o mesmo .
| Organização | Ideia | Boa para | Ruim para |
|---|---|---|---|
| Sequencial | registros um atrás do outro, desordenados ou ordenados | varrer tudo; inserir no fim se desordenado | achar um no arquivo desordenado |
| Indexada | arquivo auxiliar chave endereço | igualdade e intervalo | espaço e manutenção do índice |
| Hash (direto) | cai num balde | igualdade da chave hash | intervalo |
Hash não atende "chave entre e ". A função espalha valores próximos por baldes distintos: e não são vizinhos. Percorrer o intervalo exigiria visitar baldes sem relação de ordem. Intervalo é trabalho de arquivo ordenado ou de índice em árvore.
Não confunda arquivo sequencial com acesso sequencial. Dá para varrer um arquivo hash em ordem de balde — sequencial no dispositivo — sem que a organização seja sequencial. A organização diz onde o registro está; o método de acesso diz como o endereço chega ao dispositivo.
Métodos de acesso
Independentemente da organização, o método de acesso é o contrato entre o programa e o dispositivo.
- Sequencial. Lê-se o próximo registro depois do atual. O "endereço" é a posição na sequência; um marcador — deslocamento ou número de registro — avança de um em um. Serve para separar um registro do seguinte e para recuperar na ordem em que estão gravados. Em fita, muitas vezes é o único método barato.
- Direto. Cada bloco tem um endereço exclusivo, derivado da posição física — número do bloco, ou o tripleto cilindro/trilha/setor. Dado o endereço, o dispositivo vai lá sem passar pelos vizinhos. Quando o custo de alcançar um bloco não depende de qual bloco é, fala-se em acesso aleatório: o primeiro e o último bloco custam o mesmo. Disco com endereçamento por bloco se aproxima disso; fita, não.
- Associativo. Recupera-se um registro a partir de parte do conteúdo — um campo-chave — e não a partir da posição. O endereço lógico é a própria chave, ou um pedaço dela. Se a busca não exigir a chave inteira, pode usar só um prefixo: "nome começa com
par" em vez de "registro ".
Método de acesso e organização são coisas distintas. O mesmo arquivo hash admite varrer o próximo balde (sequencial), ir ao bloco cujo número veio de (direto) e responder "qual registro tem esta chave" (associativo). Quem muda é a pergunta feita ao arquivo.
Não confunda direto com associativo. Direto parte de um endereço físico já conhecido. Associativo parte do conteúdo e só então chega a um endereço — a chave é o pedido, não o número do bloco. No sequencial restrito falta ainda a operação de recomeçar: o marcador só anda para a frente.
Rewind no sequencial restrito
Fita com quatro ids. Nesta ordem: , , e . O marcador começa no primeiro.
Lê-se ; o marcador avança. Lê-se ; avança. Não há pedido "vá ao terceiro": só aparece depois de dois "próximo".
Quando o contrato é restrito a acesso sequencial, a interface clássica não oferece posicionamento em um deslocamento qualquer. Lê-se ou escreve-se o próximo; a cabeça lógica só avança.
O marcador está em . Para reler é preciso voltar ao início: o contrato não oferece salto para trás. Rewind devolve o marcador ao começo do arquivo. Sem essa operação, um arquivo só-sequencial não relê o primeiro registro depois de ter avançado.
Num disco com endereçamento por bloco, coloca o cursor no byte porque o modelo já é aleatório. A fita não salta para o metro ; rebobina.
Rewind não se reduz a . Seek coloca o cursor num deslocamento e pressupõe acesso aleatório: o dispositivo aceita ir ao byte sem passar pelos vizinhos. Equiparar rewind a descreve um arquivo já aleatório, em que o recomeço foi implementado como um caso particular de seek. No sequencial restrito, seek arbitrário não existe; rewind é primitiva, não atalho.
Três pares, doze bytes
Um arquivo guarda três pares , cada um com bytes, sem cabeçalho. Os ids são , e ; as notas, , e . O total é bytes.
| Par | id | nota |
|---|---|---|
Para o sistema de arquivos isso é só um vetor de bytes. Pedir "a nota do id " não é operação do sistema.
Cada par tem bytes, então o primeiro ocupa os bytes –, o segundo os bytes – e o terceiro os bytes –. O programa compara o id de cada grupo de bytes: , depois , depois . A nota está nos bytes – porque o id está aí.
Se a biblioteca trata cada par como registro de tamanho , todo registro tem o mesmo comprimento: o endereço do registro é sem reler os anteriores. O terceiro () começa em . A conta é o que o tamanho fixo acrescenta à sequência de bytes.
Quatro produtos no catálogo
Um arquivo tem quatro produtos. Cada um traz id (inteiro de bytes), nome e preço (inteiro de bytes). Os nomes são fio ( letras), prego (), cabo () e parafuso (); os ids são , , e ; os preços, , , e .
O sistema vê um vetor. Sem um acordo prévio de layout, não há "terceiro produto": há só octetos. O nome prego tem duas letras a mais que fio; se ninguém gravou o comprimento, o programa não sabe onde o segundo nome acaba e o preço começa. O programa decide a fronteira entre os campos.
Reservamos bytes por produto: de id, de nome com preenchimento, de preço. O fio cabe em das posições do nome; as outras são preenchimento.
O produto de índice começa em ; o de índice , em ; o de índice — o cabo, id — em ; o último (), em . O arquivo inteiro tem bytes. Inserir um quinto produto no meio empurra os seguintes em múltiplos de : cada sucessor ganha no deslocamento porque .
Cada registro começa com o id, um inteiro de bytes com o comprimento do nome, o nome e o preço. Os tamanhos ficam
O primeiro começa em . O segundo começa depois de bytes, em . O terceiro começa depois de . O quarto começa depois de .
| Produto | id | letras | tamanho | começa em |
|---|---|---|---|---|
| fio | ||||
| prego | ||||
| cabo | ||||
| parafuso |
O deslocamento do cabo é , pela soma dos comprimentos anteriores, não de . Sem essas leituras — ou sem um índice à parte — não há . Continua sendo arquivo de registros: a biblioteca ainda devolve campos nomeados. Só mudou a conta do sucessor.
As quatro peças ficam em nós. Os ids e são menores que e ; a raiz pergunta "id ?" e separa os dois pares. À esquerda ficam e ; à direita, e . Chegar no id desce o ramo direito e para; os nós da esquerda nem são lidos. A escolha de ramo estrutura o acesso: dá para descer sem seguir o vizinho na fita.
"O próximo depois do prego" é acesso sequencial e devolve o cabo: o marcador avança um registro, seja o próximo bloco de bytes ou o próximo comprimento.
"O bloco " é acesso direto: o dispositivo usa o endereço físico, sem varrer vizinhos.
"O registro cujo id é ", ou cujo nome começa com par, é acesso associativo: a chave — ou um prefixo — é o endereço lógico. O parafuso responde ao prefixo; a posição não é o critério de busca.
Para cada pedido, um mapa físico diferente. Igualdade do id: hash ou índice. Intervalo de preços, por exemplo entre e : só o fio (preço ) cai no intervalo; índice ou arquivo ordenado pelo preço acham isso sem varrer. Hash no id não agrupa valores próximos de preço — não diz nada sobre preço . Varredura de todos: sequencial.
Em Resumo
Lógico: campo registro arquivo. Um arquivo pode ser sequência de bytes, sequência de registros (fixos ou variáveis) ou árvore; a sequência de bytes é a visão mais livre, a árvore a mais estruturada (escolha de ramo).
Físico: sequencial, indexado ou hash (arquivo direto). Hash não serve intervalo.
Acesso sequencial avança na ordem gravada; direto usa o endereço físico do bloco; associativo recupera pela chave (ou por um pedaço dela), não pela posição.
No sequencial restrito, rewind volta ao início e é a operação canônica de recomeçar; sem ela o arquivo não relê o primeiro registro. Equiparar rewind a descreve um arquivo já aleatório, não um só-sequencial.