Лабораторная работа 8
Динамические базы данных в Турбо-Прологе

       Цель работы:
  1. Знакомство с назначением и использованием динамических баз данных.
  2. Изучение правил описания и организации динамических БД в Турбо-Прологе.
  3. Получение навыков работы с динамическими БД" записи их содержимого на диск и считывания с диска.
  4. Знакомство с использованием динамических БД при разработке программ, обучающихся в процессе работы.

1. Введение

       В Прологе реляционная база данных представляется в виде набора фактов, что позволяет использовать Пролог, как мощный язык запросов для баз данных. Его алгоритм унификации автоматически выбирает факты с правильными значениями для известных параметров и унифицирует значения для любых неизвестных параметров. Алгоритм поиска с возвратом позволяет определить все решения для формируемых запросов.

       В предыдущих работах рассматривались статические базы данных, где факты являлись частью кода программы и не могли быть изменены во время работы с программой. Принципиальным отличием, рассматриваемых ниже, динамических баз данных является то, что во время работы с программой, из них можно удалять любые, содержащиеся в ней утверждения, а также добавлять новые. Другая важная особенность динамической базы состоит в том, что она может быть написана на диск и считана с диска в оперативную память.

       Факты, принадлежащие динамическим базам данных (ДБД), обрабатываются отличным от обычных предикатов образом для того, чтобы ускорить работу с базами данных большого объема. Предикаты ДБП отличаются от обычных тем, что они описываются в отдельной секции программы - database. Манипулирование фактами в ДБД осуществляется с использованием трех стандартных предикатов.
asserta(Term) - добавляет новые факты в начало динамической базы данных.
assertz(Term) - добавляет новые факты в конец динамической базы данных,
retract(Term) - удаляет факт из динамической базы данных.
       Для модификации какого-либо факта в базе данных необходимо сначала удалить его, а затем добавить в измененном виде. Стандартные предикаты:
save("file_name") - сохранение ДБД в текстовом файле с именем file_name.
consult( "file_name ") - загрузка ДБД из текстового файла с именем file_name,
обеспечивают обмен между ОЗУ и ВЗУ данными, содержащимися в динамической базе данных.

       Следует отметить, что иногда часть информации базы данных предпочтительно иметь в виде утверждений статической БД и заносить эти данные в динамическую БД сразу же после активизации программы. При этом предикаты статической БД должны иметь другое имя, но ту же самую структуру данных. что и предикаты динамической БД. Причем описание предикатов ДБД производится в секции database, а предикатов статической БД - в секции predicates.

2. Простейшие приемы работы с динамическими БД

       В секции database декларируются предикаты, описывающие динамическую базу данных. Описание предикатов динамической БД должно предшествовать описанию всех обычных предикатов.

       В приведенной ниже программе 18 рассмотрен пример использования явной динамической базы данных, структура которой соответствует отношению
ЛИЧНОСТЬ (ИМЯ, ВОЗРАСТ, ПОЛ).
       На основе явной динамической БД, которая допускает модификацию во время работы, в программе с помощью правил определены еще три неявные базы данных:
МУЖЧИНА (ИМЯ, ВОЗРАСТ), ЖЕНЩИНА (ИМЯ, ВОЗРАСТ). РЕБЕНОК (ИМЯ, ВОЗРАСТ, ПОЛ)
       Предикат person() можно использовать точно так же, как и любые другие предикаты. Отличие лишь в том, что для него, во время выполнения программы, возможно добавление и удаление фактов. Факты, добавляемые таким образом, сохраняются в ОЗУ ЭВМ. Используя программу 18, рассмотрим простейшие приёмы работы с ДБД. Если загрузить в память ЭВМ
/* Программа 18 */
domains
name= string
age = integer
sex = m ; f
/* домены m и f состоят только из одного функтора */
database
person(name,age,sex)
predicates
male(name,age) female(name.age) child(name,agc,sex)
clauses
male(Name,Age):-person(Name,Age,m).
female(Name,Age):-person(Name,Age,f).
child(Name,Age,Sex):-person(Name,Age,Sex), Age<16.
эту программу и сформировать к ней запрос
Goal: person(X,Y,Z):
то Турбо-Пролог ответит "нет" что вызвано отсутствием данных в ДБД. Если же теперь ввести последовательно две цели
Goal: asserta(person(tom,20,m))
Goal: asserta(person(mery,18,f ))
и ввести первоначальный запрос, то ответом на него будет:
X=mery     Y=18     Z=f
X=tom      Y=20     Z=m
       Полученный ответ характеризует наличие в БД person() сведений о двух лицах, их именах, возрасте и поле, хотя никаких дополнительных фактов в текст программы не вводилось. В этом принципиальное отличие ДБД, которые организуются Турбо-Прологом в памяти ЭВМ, свободной от Пролог-программы.

       Занести информацию о Томе и Мери в ДБД нам позволил предикат asserta(). Особенность его работы видна из сопоставления двух целей и результата запроса. Данные о Томе вводились первыми, а затем данные о Мери. В ответе - первыми являются данные о Мери. Это связано с тем, что asserta(person(mery,18,f)) внес данные о Мери в начало динамической БД. Добавим в БД информацию еще о двух лицах, последовательно вводя еще две цели вида:
Goal: assertz( person( nick, 10, m))
Goal: asserta( person( ada , 9 , f ))
       Если теперь сформулировать запрос о выдаче всей информации, хранящейся в ДБД pcrson(), то ответ на него будет получен в следующей форме:
Goal: person(Name,Age,Sex),
Name=ada   	Age=9     Sex=f
Name=mery	Age=18    Sex-f
Name=tom	Age==20   Sex=m
Name=nick	Age=10    Sex=m
4
       Из сопоставления целей добавления и результатов запроса видно, что один из добавленных фактов помещен в начало ДБД, а во второй - в конец, что связано с различием в работе предикатов asserta() и assertz().

       С элементами ДБД Пролог может выполнять все операции, допустимые для фактов аналогичной структуры. Их можно искать, унифицировать, использовать в виде подцелей правил и т.д. Так, в данной программе ДБД используется в виде подцели трех правил формирования неявных БД. Используя предикаты неявных БД, можно сформировать запросы о данных по мужчинам, женщинам или детям:
Goal: male(Name,Age)
Goal: female(Name,Age)
Goal: child(N,A,S)
Name=tom Age=20
Narne=nick Age=10
2
Name=ada Age=20
Name=mery Age=10
2
N=ada A=9 S=f
N=nick A=10 S=m
2
или сформировать на их основе любые иные, простые или составные, запросы.

       Если потребуется удалить из ДБД какой-либо факт, то для этого следует воспользоваться предикатом retract(). Например, для удаления сведений о Мери следует задать цель:
Goal: retract(person(mery,_,_))
       При необходимости скорректировать какой-либо элемент ДБД его следует удалить из базы данных, а затем добавить в ДБД новый модифицированный элемент. В частности, для того, чтобы изменить возраст Тома на один год, надо ввести составную цель:
Goal:
person(tom,OldAge,Sex,Person), retract(person(tom,_,_)), NewAge=OldAge+1,!, asserta(person(tom,NewAge,Sex,Person)) ,
которая удалит старый факт и добавит в ДБД кодифицированный факт. Результат проведенных преобразований ДБД можно получить, как ответ на запрос ,
Goal: person(Name,Age,Sex)
Name=tom   Age=21    Sex=m
Name=ada   Age=9     Sex=f
Name=nick  Age=l0    Scx=m
3
       Динамическая база данных целиком может быть сохранена в текстовом файле с помощью вызова предиката save с именем текстового файла в качестве параметра. Например, после выполнения цели:
Goal: save( "person.dba" )
файл mydata.dba будет похож на обычную программу на Турбо-Прологе с фактами на каждой строке. Такой файл может быть позднее считан в память, используя:
Goal: consult( "person.dba" ).
       Заданное действие выполнится, если программа в файле не содержит ошибок. При наличии ошибок считывание из файла данных в динамическую БД не произойдет.

       Задание 1.
Загрузите программу 18 и выполните все перечисленные в данном разделе действия по заполнению и модификации динамической базы данных person(), а также по запросом к явной ДБД и неявным БД. Сохраните результирующую ДБД в файле "person.dba", а программу в файле "1аb8-1.pro". Просмотрите содержимое файла "person.dba", а затем снова загрузите программный файл. Запустите программу на выполнение и введите запрос person(X,Y,Z). Какой получился результат и почему? Загрузите ДБД из файла "person.dba" и введите запрос person(X,Y,Z). Какой в этом случае получился результат и почему?

       Ранее уже не раз отмечалось, что любая программа на Прологе - это набор фактов и правил, которые представляют собой своеобразную базу данных, на которой Пролог выполняет логический вывод. В свою очередь, динамические базы данных - это набор фактов, который может изменяться при работе программы.

       Из этих двух посылок следует важнейший вывод: Пролог допускает изменение программ во время их выполнения! И эти изменения можно выполнять, используя динамические базы данных.

3. Связь статических и динамических баз данных

       В предыдущем разделе было показано, что для того, чтобы начать работать с динамической БД, требуется либо доступный для загрузки динамической БД файл на диске, либо начальная загрузка динамической базы вручную. Вызвано это тем, что Пролог формирует динамическую базу в оперативной памяти. Выключение компьютера или просто выход из программы могут привести к потере данных. В этих условиях наиболее ценные данные можно представить фактами статических база данных непосредственно в теле программы.

       При использовании такого подхода, для возможности изменения данных в процессе работы программы или добавления новых фактов, следует перезаписать данные из статической в динамическую БД и перейти к работе с ДБД.

       В программе 19 используются две базы данных одинаковой структуры
АДРЕС (ОРГАНИЗАЦИЯ, УЛИЦА, ДОМ, ГРУППА_ОРГАНИЗАЦИЙ)
       Одна из них является динамической и описана предикатом address() в секции database, вторая - статической и описана предикатом adres() в секции predicates. Предикат place() связывает месторасположение организации в городе с ее адресом.

       Процедура р1асе() накладывает ограничение один-ко-многим при доступе к ДБД address(), что обеспечивает целостность отношений при обработке запросов.

       Предикаты school() и bank() описывают две неявные БД, обеспечивающие пользовательский интерфейс к динамической БД.

       Процедура load_dbd служит для занесения в ДБД address() информации из статической БД adres(). В этой процедуре используется уже знакомый нам метод отката после неудачи, который позволяет перебрать все утверждения предиката adres() и добавить соответствующие им факты в ДБД.
/* Программа 19 */
domains
firm, street, grup = symbol
house = integer
database
address(firm, street, house, grup)
predicates
adres( firm, street, house, grup )
place( firm. street, house, grup )
load_dbd
del(firm)
school(firm)
bank(firm)
clauses
adres("ЛTA","Инcтитутcкий пер.",5,"Bуз").
adres("CП6ЭTУ","ул. проф. Попова" ,5 ,'"Вуз"). adres("ЛесПромБанк","Крапивный пер.",2,"Банк").
load_dbd:- adrcs(X,Av,N.G),
assertz(address(X,Av,N,G)).
fail.
load_dbd:- !.
del(Firm) :- retract(address(Firm,_,_,_)).
place(X,St,H,G) :- bound(X),address(X,St,H,G), !.
place(X.St.H,G) :- free(X), address(X,St,H,G).
school(Firm) :- рlасe(Firm,St,H,"Вуз").
write(St," ",H), nl.
bank(Fiim) :- place(FirmX,St,H,"Банк").
write(St," ",H), nl.
       Предикат del(X) имеет всего один аргумент и определяется правилом, которое удаляет из ДБД факт для организации, имеющей наименование то же, что и аргумент Х предиката.

       Закончив описание программы 19, перейдем к работе с базами этой программы.

       Загрузим программу в память и запустим ее на выполнение. Если ввести запрос:
Goal :adres(Firm,_,_,_) .
то в ответе будет список из трех организаций по числу фактов, входящих в статическую БД. Ответ на запрос:
Goal: place(Firm, _,_,_}
будет "нет", так как нет данных в ДБД, хотя в статической они заданы. Но предикат place() был определен па ДБД. Если до формирования запроса загрузить динамическую базу данных из статической, т.е. сформировать цель
Goal:(load_dbd,place(Firm,_, _,Grup)
то ответом будет
Firm=ЛTA                Grup=Вуз
Firm=СПбЭТУ             Grup=Вуз
Firm= ЛесПромБанк       Grup=Банк
3.
       При этом, операцию загрузки динамической БД следует выполнять только один раз во время сеанса работы с программой. Это обусловлено тем, что повторное обращение к предикату load_dbd вызовет добавление динамической базы данных, уже существующим в ней набором фактов. То есть произойдет дублирование данных.

       Задание 2.
Введите программу и выполните описанные выше запросы. Повторно введите последний запрос и убедитесь в дублировании данных. Приведите ДБД в исходное состояние, используя предикат del() и сформируйте четыре запроса об адресе ЛТА, используя четыре различных предиката (adres, address, place, school). В чем состоит различие запросов? Сформируйте запросы: "Какие организации расположены в домах с номером 5?", "Найдите адреса всех ВУЗов?", "Адрес ПромстройБанка?". Сколько имеется способов построения каждого из этих запросов и в чем их различие? Запросы и их результаты привести в отчете по работе.

       Использование неявных баз данных позволяет существенно упростить запросы за счет организации пользовательского интерфейса с ДБД. Его использование не требует от пользователя знания всех атрибутов ДБД и последовательности их описания Б предикате, декларирующем ДБД.

       Кроме этого, неявные БД позволяют фильтровать исходную динамическую БД в соответствии с некоторыми групповыми признаками. При этом у администратора БД остается возможность доступа непосредственно к фактам ДБД.

4. Процедура работы с динамической БД, обучающаяся у пользователя

       Реализация последнего запроса задания 2 показывает отсутствие требуемых данных в БД и, как следствие, необходимость их добавления. Однако добавление новых данных требует выполнения ряда операций, описанных в предыдущих разделах. Для пользователя, не знающего структуру динамической БД, это является невозможным, а для администратора БД это представляет собой нудный трудоемкий процесс.

       В этих условиях встает задача построения более интеллектуальной процедуры доступа к динамической БД, которая не только обеспечивала бы ограничения "один-ко-многим", но и обучалась бы у пользователя, формируя динамическую БД.
/* Программа 19 */

...
place(X,St,H,G) :- bound(X),bound(G). write("введи для ",Х ), nl, write("улица "), readln(St),
write ("дом "). readreal(H),
assertz( address(X,St,H,G) ),!.
place(X,St,H,_) :- bound(X),
write("введи для ",Х ), nl,
write("улица "), readln(St),
write ("дом "). readreal(H),
writc("группа "), readln(G),
assertz( address(X,St,H,G) ),!.
...
       Если в процедуру place() добавить еще два правила, то она не просто завершается неудачей при невозможности найти нужные данные в ДБД address(), а переключается на другую стратегию и получает сведения от пользователя.

       При этом пользователь будет выступать в качестве альтернативного источника знаний. Процедура place() учится на своем опыте, вводя новые ответы в ДБД.

       Первое правило запрашивает у пользователя адрес конкретной организации, отсутствующей в БД и относящейся к определенной группе. Это имеет место при запросах с использованием неявных баз данных, когда известен некоторый групповой признак, характерный для конкретной неявной БД.

введи для ПромСтройБанк улица Невский пр. дом 38
Goal:
bank("ПромСтройБанк")
Невский пр. 38
True
       Так, если в исходном варианте процедуры рlасе() запрос о ПромСтройБанке оканчивался неудачей (False), то добавление в процедуру р1асс() первого правила приведет к запросу со стороны программы адреса банка и добавления нового факта в динамическую БД address().

       Результат выполнения этого действия с программой можно увидеть, если ввести запрос на вывод содержимого всей динамической БД:
Goal: address(Firm, _ ,_,Grup)
Firm=ЛTA                Grup=Вуз
Firm=СПбЭТУ             Grup=Вуз
Firm=ЛесПромБанк        Grup=Банк
Firm=ПромСтройБанк      Grup=Банк
4
       Динамическая БД содержит четыре факта, последний из которых теперь соответствует ПромСтройБанку, у которого группа - "Банк", хотя это не вводилось. Эта группа позволяет системе относить новый факт к неявной базе bank(). В этом можно убедиться, сформировав запрос на вывод всех 6анков Goal:bank(Name).

       Если же нас интересует информация об организации, имеющей групповой признак, для которого не определена неявная БД, то можно воспользоваться интерфейсной БД place(). Однако, ответ на запрос р1асe("СевЗапМебель",St,Н,G) будет False, так как не определен признак группы и не выполняется первое из двух новых правил процедуры place().

       Если же в процедуру р1асе() добавить второе правило и повторить запрос, то система потребует ввести адрес и группу, к которой относится данная организация.
Goal:
рlасe("СевЗапМебель",St,Н,G)
улица Дегтярная ул.
дом 4
группа АО
True
       После ввода процедура сама добавит в True динамическую БД новый факт. Убедиться в этом можно, если сформировать запрос на вывод содержимого всей БД address(), которая теперь должна содержать данные уже по пяти организациям.

       Но в текущий момент вся информация ДБД хранится R оперативной памяти и выход из программы, а тем более выключение компьютера, приведет к потере всех данных. Избежать этого можно, сохранив ДБД в файле.

       Задание 3.
Добавьте в процедуру р1асe() одно, а затем второе правою и выполните описанные в данном разделе действия по модификации динамической БД и запросам к явной и неявным БД. Сохраните ДБД в файле "adres.dba", а программу - в файле "1аb8-2.рго". Просмотрите содержимое файла "adres.dba", а затем снова запустите программу на выполнение и выполните ряд запросов, содержание которых и результат их выполнения привести в отчете по работе.

5. Расширение базы данных в файлы

       Рассмотренный подход к записи и считыванию ДБД, с использованием save и consult, дает хорошие результаты при небольших размерах БД. Связано это с тем, что факты динамической БД являются частью Пролог-программы и, следовательно ограничиваются размером свободной оперативной памяти. Для увеличения объема хранимой информации можно организовать базы данных, которые хранятся не в оперативной памяти, а в файлах на диске.

       Это расширяет возможность баз данных, так как при их размещении в файлах единственным ограничением является размер свободного дискового пространства. Это означает, что базы данных Турбо-Пролога могут достигать десятков мегабайт.

       Предикат readterm делает возможным доступ к фактам R файле. Он может читать любой объект, записанный в файл с помощью предиката write и имеет вид:
readterm( DomainName , TermRecord).
где DomainName - это имя области типов данных, TermRecord - это терм. который связывается с объектом чтения, при условии его согласования с описанием домена.

       Факты, которые описывают предикаты базы данных, могут быть обработаны так, как если бы они были термами. Это возможно благодаря домену dbasedom, который автоматически декларируется системой Турбо-Пролог и образует ОДНУ альтернативу для каждого предиката базы данных. Он описывает каждый предикат базы данный функтором и доменами аргументов данного предиката. Например, ПУСТЬ в Пролог-программе имеются следующие декларации баз данных:
database
person(name, age, sex)
address(firm, street, house, grup)
       В этом случае система Турбо-Пролог автоматически сгенерирует соответствующий этим декларациям домен dbasedom:
domains
dbasedom = person(name, age, sex) ; address(firm. street, house, grup)
который может быть использован, как и любой другой предопределенный домен Пролог- программы.

       Рассмотрим простейший пример организации базы данных с использованием файла на диске. За основу примем упрощенный вариант программы 19, в котором база данных address() размещается в файле последовательного доступа "adres.dba".

       Данному примеру соответствует программа 20. в которой интерфейс с явной БД обеспечивается с использованием предиката рlасе(), структура которого аналогична программе 19. Однако процедура, его определяющая, отличается тем, что в се правилах предусмотрено обращение к фактам дисковой БД.
/* Программа 20 */
/* обучающаяся запросная система к БД "adres.dba" */
domains
firm, street, grup = symbol
house = integer
file = file_bd
database
address(firm, street, house, grup)
predicates
place(firm, street, house, grup)
my_read(dbasedom )
my_append( dbasedom )
next_rec( file )
clauses
my_read(Record) :- openread( file_bd ,"adres.dba" ),
readdevice( file_bd ),
next_rec( file_bd ),
readterm( dbasedom , Record).
my_append(Record) :- openappend( file_bd, "adres.dba" }.
writedevice( file_bd ),
write(Record,"\n"),nl,
closefile(file_bd).
next_rec(_).
next_rec(File) :- not(eof(File)), next_rec(File).
place(F,S,H,G);- bound(F).my_read(R), R=address(F.S,H.G),!.
place(F.S,H,G):- free(F), my_read(R), R=address(F,S.H.G).
place(F.S.H.G):- bound(F), free(S), free(H),
readdevice(key board),
write("введи для ",F),nl,
write("улица "), readln(S),
write("дом "), readreal(H),
write("группа ").readln(G),
closefile(file_bd),
my_append( address(F,S,H,G) ).
       Для использования в программе файлов, следует ввести файловый домен, где определяется логическое имя файла. В нашей программе таким логическим имеем будет file_bd. Это имя предикатами программы связывается с именем файла БД.

       В программе 20 определены два предиката для чтения и добавления домена БЛ. Это предикаты my_read и my_append. Предикат next_rec по структуре похож ни предикат repeat и служит для перехода от одной записи файла к другой, пока не будет обнаружен конец файла.

       В процедуре place два первых правила в качестве второй подцели вызывают предикат my_read(R), который связывает терм R с текущей записью файла БД.

       Третья подцель этих двух правил унифицирует текущую запись со структурой address(F,S,H,G). Если унификация невозможна, происходит откат к предикату my_read(R), который связывает переменную R со следующей записью файла. И так будет продолжаться до тех пор, пока унификация не будет успешной, или пока не будет достигнут конец файла.

       Если унификация завершится успешно, то переменные F, S, H, G будут иметь те же значения, что и поля текущей записи БД, а вес правило, как и процедура в целом, будет успешно доказанным. Если унификация как первого, так и второю правила завершилась неудачей при достижении конца файла, то система перейдет к доказательству третьего правила процедуры place().

       В процедуре my read() первая подцель связывает логическое имя file_db с дисковым DOS-файлом "adres.dba" и открывает его для чтения.

       Вторая подцель назначает файл с логическим именем file_db стандартным устройством ввода. Это означает, что все встречающиеся далее предикаты типа read будут выполнять ввод данных из файла, а не с клавиатуры, которая по умолчанию являлась стандартным устройством ввода

       Третья подцель служит для организации повторного выполнения, следующих подцелей при откатах. Следует отметить, что предикат next_rec() истинен всегда, если не обнаружен конец ( eof() ) записей в дисковом файле.

       Так как стандартным устройством ввода сейчас установлен дисковый файл, то именно из него четвертая подцель считывает в переменную Record терм, структура которого соответствует структуре домена базы данных. Иначе говоря, выполняется считывание в переменную Record содержимого текущей записи файла, структура которой должна соответствовать описанной в программе структуре БД.

       В процедуре my append() первая подцель связывает логическое имя file_db с дисковым DOS-файлом "adres.dba" и открывает его для добавления.

       Вторая подцель назначает файл с логическим именем file_db стандартным устройством вывода. Это означает, что все встречающиеся далее предикаты типа write будут выполнять вывод данных в файл, а не на экран дисплея, который является стандартным устройством вывода по умолчанию.

       Третья подцель выводит (добавляет в конец файла) новую запись, значение которой передано в данную процедуру через переменную Record. Кроме этого в конце записи дополнительно -выводится символ перевода на новую строку "\n".

       После выполнения этих действий четвертая подцель закрывает открытый для добавления файл.

       Основным режимом данной программы является режим ответов на запросы, который требует постоянного доступа по чтению s. дисковому файлу. При этом устройство ввода переназначено с клавиатуры на файл БД. Однако при отсутствии в БД нужных данных, программа переходит в режим обучения и требует от пользователя задания новых данных.

       В третьем правиле процедуры place() для того, чтобы обеспечить возможность ввода данных с клавиатуры, используется предикат readdevice(keyboard) который устанавливает в качестве стандартного устройства ввода клавиатуру. После этого обеспечивается запрос на ввод новых данных. Закрывается рабочий файл, который был открыт для чтения. И выполняется добавление новой записи в дисковый файл.

       Следует отметить, что в этом примере рассмотрен простейший случай доступа к файловым данным. Он приведен с целью иллюстрации принципа построения динамических БД и их расширения в файловые структуры.

       Задание 4.
Загрузите программу 20. разберитесь в ней и выполните ряд описанных в предыдущем разделе действий по работе с БД, сохранению в файле "adres.dba". Познакомьтесь по приложению 1 с предикатами для работы с файлами. Доработайте программу 20 так, чтобы в ней можно было пользоваться неявными базами данных school() и bank(), аналогично программе 19. Запустите программу и введите ряд запросов, содержание которых и результат выполнения включить в отчет по работе.

       Выше использовались файлы последовательного доступа. Сложность работы с ними возникает уже при выполнении таких простых действий, как удаление данных. Эта операция потребует реорганизации исходное файла БД, что вызовет непроизводительные затраты времени. Поэтому, при построении файловых БД используются файлы прямого доступа с индексными файлами. Вместо индексных файлов, в ряде случаев, более целесообразно применять метод двоичного поиска или хешенирования. Эти методы значительно укоряют доступ к фактам БД.

6. Содержание отлегла по лабораторной работе

       Отчет по лабораторной работе должен содержать:
  1. Программы работы с динамическими БД, использованные при выполнении данной работы, а также описание структуры этих программ.
  2. Содержимое файловых БД, сохраненных на диске.
  3. Результаты выполнения заданий 1,2,3, и 4.