Міністерство освіти і науки України
Національний університет
«Львівська політехніка»
кафедра САПР
Лабораторна робота №2
з дисципліни: «Організація баз даних і знань»
на тему:
ПРЯМИЙ МЕТОД ДОСТУПУ ДО ФАЙЛІВНА ЗОВНІШНІХ ЗАПАМ’ЯТОВУЮЧИХ ПРИСТРОЯХ
МЕТА РОБОТИ
Розглянути органiзацiю i ведення файлiв прямого доступу; набути практичнi навички у програмуваннi алгоритмiв доступу хешуванням.
2. КОРОТКІ ТЕОРЕТИЧНІ ВІДОМОСТІ
МЕТОД ПРЯМОГО ДОСТУПУ
Головною особливiстю прямого методу доступу є взаємна однозначна вiдповiднiсть мiж ключем запису i його фiзичною адресою. Фiзичне розмiщення запису визначається безпосередньо iз значення ключа.
Створивши файл прямого доступу i видiливши для нього необхiдну дiлянку пам’ятi, можна вставляти записи у будь-якi мiсця файла. Перевага такого пiдходу над послiдовною органiзацiєю файла полягає у тому, що вдається отримати запис за заданим значенням ключа без попереднього перегляду всiх попереднiх записiв файла.
ЕФЕКТИВНІСТЬ ДОСТУПУ дорiвнює одиницi.
ЕФЕКТИВНІСТЬ ЗБЕРІГАННЯ залежить вiд густини ключiв. Якщо густина низька, пам’ять використовується неефективно, оскiльки резервуються адреси, що вiдповiдають вiдсутнiм ключам. У цьому випадку доцiльно використовувати для органiзацiї файла метод хешування. Пряму адресацiю можна важати частковим випадком методу хешування.
ПОШУК
Для того щоб за даним значенням ключа k знайти вiдповiдний запис, необхiдно визначити h(k) i потiм органiзувати лiнiйний пошук у блоцi, номер якого дорiвнює h(k). Цей пошук буде продовжуватися доти, поки не буде знайдений запис, значення первинного ключа якого збiгається iз заданим.
ВСТАВЛЯННЯ
Щоб вставити у файл новий запис, потрiбно за допомогою методу лiнiйного пошуку у блоцi, номер якого визначається значенням h(k), знайти вiльне мiсце. Пiсля цього на мiсце знайденого вiльного запису необхiдно розмiстити новий. Якщо при спробi помiстити новий запис у файл виявляється, що у знайденому блоцi немає вiльного мiсця, вважають, що блок переповнений.
ВИДАЛЕННЯ
Для видалення запису iз файла потрiбно, використовуючи метод лiнiйного пошуку, знайти запис у блоцi, номер якого дорiвнює h(k). Якщо запис буде знайдено то вiн видаляється, якщо нi, то очевидно, що блок був переповнений i необхiдно продовжити пошук.
МОДИФІКАЦІЯ
Якщо необхiдно модифiкувати запис, то потрiбно знайти цей запис i замiнити старi поля на новi. Нiяких iнших змiн не потрiбно.
ПЕРЕПОВНЕННЯ
Якщо необхiдно вставити новий запис, а у блоцi, призначеному для цього, немає мiсця, цей запис розмiщується у перший блок переповнення, в якому є вiльне мiсце. Пiсля цього необхiдно вставити цей запис у зв’язаний список записiв iз тим самим значенням функцiї хешування.
ІНДИВІДУАЛЬНЕ ЗАВДАННЯ
Написати програму методу прогресуючого переповнення, яка реалiзує такi функцiї:
1. Друк бази даних.
2. Зчитування запису.
3. Введення запису.
4. Видалення запису.
5. Модифiкацiя запису.
6. Вихiд.
Текст програми
program lab_2;
uses Crt;
type base=record
id,phone:integer;
kraina,name,partyranymic, surname,adresa,nazwa,year,wanr:string;
n_vustavku:byte;
end;
myfile=file of base;
const size=10;
var f,temp,gr:myfile;
hudownuk,hudownukn:base;
s,str,st:string;
m1,m2,m3,d:integer;
b,pb:boolean;
label l1,l2,l3;
function FileExists(FileName: String): Boolean;
var
F: file;
begin
{$I-}
Assign(F, FileName);
Reset(F);
Close(F);
{$I+}
FileExists := (IOResult = 0) and (FileName <> '');
end;
procedure viewbase(filename:string);
label gt;
var kil:integer;
begin
assign(f,filename);
reset(f);
kil:=0;
writeln('_______________________________________________________________________________');
writeln('|ID| kraina |Prizvuhe| Name |adresa| Tel |partyranymic| nazwa |year|wanr');
writeln('-------------------------------------------------------------------------------');
while not EOF(f) do
begin
read(f,hudownuk);
if hudownuk.id<>0 then
writeln('|',hudownuk.id:2,'|',hudownuk.kraina:8,'|',hudownuk.surname:7,'|',hudownuk.name:6,'|',hudownuk.adresa:6,'|',
hudownuk.phone:5,'|',hudownuk.partyranymic:12,'|',hudownuk.nazwa:8,'|',hudownuk.year:4,'|',hudownuk.wanr:8);
end;
close(f);
end;
{---------------------------------------------------------------------------------------------------}
procedure init(filename:string);
var i:integer;
begin
assign(f,filename);
rewrite(f);
hudownuk.id:=0;
hudownuk.kraina:='';
hudownuk.surname:='';
hudownuk.name:='';
hudownuk.adresa:='';
hudownuk.phone:=0;
hudownuk.partyranymic:='';
hudownuk.nazwa:='';
hudownuk.year:='';
hudownuk.wanr:='';
hudownuk.n_vustavku:=0;
for i:=0 to (size*size-1) do
write(f,hudownuk);
close(f);
end;
{---------------------------------------------------------------------------------------------------}
procedure putbase(filename:string; newhudownuk:base);
var ins:boolean;
i,hash,beg,en:integer;
begin
assign(f,filename);
reset(f);
ins:=false;
hash:=newhudownuk.id mod 10;
beg:=hash*size;
en:=beg+size-1;
while beg<=en do begin
seek(f,beg);
read(f,hudownuk);
if (hudownuk.id=0) and (ins=false) then begin seek(f,beg); write(f,newhudownuk); ins:=true; end;
beg:=beg+1;
end;
if ins=false then begin
seek(f,size*size);
while not EOF(f) do begin
read(f,hudownuk);
if (hudownuk.id=0) and (ins=false) then begin seek(f,filepos(f)-1); write(f,newhudownuk); ins:=true; end;
end;
end;
if ins=false and EOF(f) then write(f,newhudownuk);
close(f);
end;
procedure delbase(filename:string; n:integer);
var i,hash,beg,en:integer;
del:boolean;
delhudownuk:base;
begin
assign(f,filename);
reset(f);
delhudownuk.id:=0;
delhudownuk.kraina:='';
delhudownuk.surname:='';
delhudownuk.name:='';
delhudownuk.adresa:='';
delhudownuk.phone:=0;
delhudownuk.partyranymic:='';
delhudownuk.nazwa:='';
delhudownuk.year:='';
delhudownuk.wanr:='';
delhudownuk.n_vustavku:=0;
del:=false;
hash:=n mod 10;
beg:=hash*size;
en:=beg+size-1;
while beg<=en do
begin
seek(f,beg);
read(f,hudownuk);
if (hudownuk.id=n) and (del=false) then begin b:=true; seek(f,filepos(f)-1); write(f,delhudownuk); break; end
else del:=false;
beg:=beg+1;
end;
if del=false then
begin
seek(f,size*size);
while not EOF(f) do
begin
read(f,hudownuk);
if (hudownuk.id=n) then begin b:=true; seek(f,filepos(f)-1); write(f,delhudownuk); break; end
end;
end;
close(f);
end;
{---------------------------------------------------------------------------------------------------}
function isid(filename:string; n:integer):boolean;
var i,hash,beg,en:integer; b, ready:boolean;
f:file of base;
begin
assign(f,filename);
reset(f);
b:=false;
ready:=false;
hash:=n mod 10;
beg:=hash*size;
en:=beg+size-1;
while beg<=en do
begin
seek(f,beg);
read(f,hudownuk);
if (hudownuk.id=n) and (b=false) then begin b:=true; ready:=true; break; end
else b:=false;
beg:=beg+1;
end;
if ready=false then
begin
seek(f,size*size);
while not EOF(f) do
begin
read(f,hudownuk);
if (hudownuk.id=n) and (b=false) then begin b:=true; ready:=true; break; end
else b:=false;
end;
end;
isid:=b;
close(f);
end;
procedure editbase(filename:string);
label e1,e2,e3,e4,e6,e7,e8,e9,endd;
label e5;
var i,code,r,hash,beg,en:integer;
sn:string;
z,newhudownuk,rm:base;
del:boolean;
begin
assign(f,filename);
reset(f);
e1: clrscr;
writeln('Enter ID:');
readln(sn);
val(sn,r,code);
if code <> 0 then begin
writeln('Error!', code);
goto e1
end
else
newhudownuk.id:=r;
while not EOF(f) do
begin
read(f,rm);
if (newhudownuk.id=rm.id) then begin newhudownuk:=rm; break; end;
end;
b:=isid(filename,newhudownuk.id);
if (b=false) then begin writeln('ID nemae!'); readln; goto endd; end
else begin
writeln('Enter kraina:');
readln(sn);
if length(sn)=0 then begin newhudownuk.kraina:=rm.kraina; goto e2 end
else newhudownuk.kraina:=sn;
e2: writeln('Enter prizvuche:');
readln(sn);
if length(sn)=0 then begin newhudownuk.surname:=rm.surname; goto e3 end
else newhudownuk.surname:=sn;
end;
e3: writeln('Enter name:');
readln(newhudownuk.name);
e4: writeln('Enter adres:');
readln(newhudownuk.adresa);
e5: writeln('Enter phone:');
readln(sn);
if length(sn)=0 then begin newhudownuk.phone:=rm.phone; goto e6 end
else begin
val(sn,z.phone,code);
if code <> 0 then begin
writeln('Error!', code);
goto e5
end
else
newhudownuk.phone:=z.phone;
end;
e6: writeln('Enter partyranymic:');
readln(sn);
if length(sn)=0 then begin newhudownuk.partyranymic:=rm.partyranymic; goto e7 end
else newhudownuk.partyranymic:=sn;
e7: writeln('Enter nazwa:');
readln(newhudownuk.nazwa);
e8: writeln('Enter year:');
readln(newhudownuk.year);
e9: writeln('Enter wanr:');
readln(newhudownuk.wanr);
close(f);
reset(f);
del:=false;
hash:=newhudownuk.id mod 10;
beg:=hash*size;
en:=beg+size-1;
while beg<=en do
begin
seek(f,beg);
read(f,hudownuk);
if (hudownuk.id=newhudownuk.id) and (del=false) then begin b:=true; seek(f,filepos(f)-1); write(f,newhudownuk);
break; end
else del:=false;
beg:=beg+1;
end;
if del=false then
begin
seek(f,size*size);
while not EOF(f) do
begin
read(f,hudownuk);
if (hudownuk.id=newhudownuk.id) then begin b:=true; seek(f,filepos(f)-1); write(f,newhudownuk); break; end
end;
end;
endd:
close(f);
end;
procedure searchbase(filename:string; s:string);
var i:integer;
begin
assign(f,filename);
reset(f);
writeln('_______________________________________________________________________________');
writeln('|ID|kraina|Prizvuhe|Name|adresa|Tel|partyranymic|nazwa|year|wanr');
writeln('-------------------------------------------------------------------------------');
while not EOF(f) do
begin
read(f,hudownuk);
if ((pos(s,hudownuk.kraina)<>0) or (pos(s,hudownuk.surname)<>0)) then begin
writeln('|',hudownuk.id:2,'|',hudownuk.kraina:10,'|',hudownuk.surname:10,'|',hudownuk.name:6,'|',
hudownuk.adresa:11,'|',hudownuk.phone:5,'|',hudownuk.partyranymic:10,'|',hudownuk.nazwa:8,'|',hudownuk.year:3,'|');
end
end;
close(f);
end;
procedure enter(filename:string; op:integer;var q:boolean);
label k1,k2,k3,k4,k5,k6,k7,en;
var sn:string;
code:integer;
z:base;
begin
q:=true;
k1: clrscr;
writeln('Enter ID:');
readln(sn);
val(sn,z.id,code);
if code <> 0 then begin
writeln('Error:', code);
goto k1
end
else
hudownukn.id:=z.id;
b:=isid(filename,hudownukn.id);
if ((b=true) and (op=1)) then begin writeln('ID vge e!'); readln; q:=false; goto en; end
else if ((b=false) and (op=2)) then begin writeln('ID ne dopustume!'); readln; q:=false; goto en; end
else begin
writeln('Enter kraina:');
readln(hudownukn.kraina);
writeln('Enter prizvuche hudownuka:');
readln(hudownukn.surname);
k2: writeln('Enter name hudownuka:');
readln(hudownukn.name);
k3: writeln('Enter adresa vustavku:');
readln(hudownukn.adresa);
k4: writeln('Enter phone vustavku:');
readln(sn);
val(sn,z.phone,code);
if code <> 0 then begin
writeln('Error!', code);
goto k4
end
else
hudownukn.phone:=z.phone;
writeln('Enter partyranymic hudownuka:');
readln(hudownukn.partyranymic);
k5: writeln('Enter nazwa kartunu :');
readln(hudownukn.nazwa);
k6: writeln('Enter year napusanna:');
readln(hudownukn.year);
k7: writeln('Enter wanr kartunu:');
readln(hudownukn.wanr);
end;
en:
end;
begin
l1:clrscr;
writeln(' Menu ');
writeln('1. Open database');
writeln('2. New database');
writeln('3. Exit');
readln(m1);
case m1 of
1:begin
clrscr;
writeln('Enter dorogu do database:');
readln(s);
if (FileExists(s)=false) then
begin
writeln('File nemae!');
readln;
goto l1;
end
else goto l2;
end;
2:begin
clrscr;
writeln('Enter dorogu do database:');
readln(s);
if (FileExists(s)=true) then
begin
writeln('File vge e v nayavnosti!');
readln;
goto l1;
end
else begin
init(s);
goto l2;
end;
end;
3: exit;
end;
l2: clrscr;
writeln('');
writeln(' Menu');
writeln('0. Viev');
writeln('1. Insert');
writeln('2. Delete');
writeln('3. Edit');
writeln('4. Searsh');
writeln('5. Prev_menu');
writeln('6. Exit');
readln(m2);
case m2 of
0:begin
clrscr;
viewbase(s);
readln;
goto l2;
end;
1: begin
clrscr;
enter(s,1,pb);
if pb=true then
putbase(s,hudownukn);
clrscr;
viewbase(s);
readln;
goto l2;
end;
2:begin
clrscr;
viewbase(s);
write('Enter ID:');
readln(d);
b:=isid(s,d);
if b=true then
delbase(s,d)
else begin writeln('Nema takoho ID');
readln;
end;
clrscr;
viewbase(s);
readln;
goto l2;
end;
3: begin
clrscr;
viewbase(s);
editbase(s);
clrscr;
viewbase(s);
readln;
goto l2;
end;
4:begin
clrscr;
writeln('Vvedit prizvuche:');
readln(str);
searchbase(s,str);
readln;
goto l2;
end;
5: goto l1;
6: exit;
end;
end.
Результати виконання програми
Головне меню програми:
При виборі пункту 1,програма відкриває базу даних і просить ввести шлях до неї:
І після цього відкривається меню бази даних:
При введенні числа 0, відкривається меню перегляду бази даних.
При введенні числа 1, відкривається меню вставки елемента в базу даних.
При введенні числа 2, відкривається меню видалення елемента з бази даних і потрібно лише ввести ID елемента наприклад 9.
При введенні числа 3, відкривається меню редагування елемента бази даних.
При введенні числа 4, відкривається меню пошуку елемента в базі даних і потрібно ввести дату запису або прізвище:
При введенні числа 5, відбувається повернення в головне меню.
При введенні числа 6, вихід з програми.
При виборі пункту 2, головного меню, програма створює нову базу даних і просить ввести шлях до неї
При виборі пункту 3, головного меню, вихід з програми.
Висновок
На цій лабораторній роботі я розглянув органiзацiю i ведення файлiв прямого доступу; набув практичнi навички у програмуваннi алгоритмiв доступу хешуванням.