| Code: ------------------------------------------------------------------------------ | УРАЛЬСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ | | Кафедра Автоматики и Информационных Технологий | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | О Т Ч Е Т | | по практическому заданию | | курса | | " Автоматизированные банки данных и базы знаний " | | | | | | | | | | | | | | | | | | | | Студент Шабаршин А.А | | Преподаватель Сухарев Ю.П | | Оценка ____________ | | Дата сдачи ____________ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Е К А Т Е Р И Н Б У Р Г | | | | 1 9 9 4 | | | | | | | |______________________________________________________________________________| 1 -------------------------------------------------------------------------------- Практическое задание состояло в создании базы данных библиографических карточек и программы управления этой базой . Поля базы данных : 1 Фамилия И.О. автора 2 Фамилия И.О. второго автора 3 Фамилия И.О. третьего автора 4 Название книги 5 Язык оригинала 6 Издательство 7 Город издания 8 Год издания 9 Количество страниц 10 Код десятичной классификации 11 Шифр темы 12 Дополнительные сведения
База данных получила такую структуру :
ЗАПИСЬ# FIELD_NAME FIELD_TYPE FIELD_LEN FIELD_DEC 1 NAME C 020 000 2 NAME2 C 020 000 3 NAME3 C 020 000 4 TITLE C 040 000 5 LANG C 004 000 6 PUBL C 020 000 7 CITY C 010 000 8 YEAR N 004 000 9 PAGE N 003 000 10 CODE N 010 000 11 CIPHER C 010 000 12 REM M 010 000
Созданные файлы: BIBLI.DBF - файл базы данных BIBLI.DBT - файл примечаний BIBLI.PRG - командный файл BIBLI.IDX - индексный файл
2 -------------------------------------------------------------------------------- В управляющей программе реализованы функции : 1 Редактирование карточек 2 Добавление карточки в базу данных 3 Удаление карточки из базы данных 4 Печать библиографической карточки 5 Поиск - по автору - по названию книги - по языку оригинала - по издательству - по городу издания - по году издания - по коду - по шифру - повторный по любому пункту 6 Фильтрация - по автору - по названию книги - по языку оригинала - по издательству - по городу издания - по году издания - по шифру - отмена фильтра 7 Индексация - по первому автору - по названию книги - по языку оригинала - по издательству - по городу издания - по году издания - по количеству страниц - по коду - по шифру 8 Возвращение в ДОС 3 -------------------------------------------------------------------------------- Текст программы с комментариями. set talk off && Запретить вывод протокола работы set bell on && Разрешить звуковой сигнал set status off && Запретить строку статуса set escape off && Запретить прерывание работы по ESC set confirm on && Включить подтверждение при вводе поля set scoreboard off && Не set date german && Установить формат даты DD.MM.YY set exact off && Сравнивать две строки до конца одной из них set memowidth to 80 && Установить ширину вывода поля MEMO set color to n/rg,n/g && Установка символьных атрибутов @ 0,0 clear to 24,79 && Очистка экрана @ 0,0 to 24,79 double && Начертить двойную рамку во весь экран set color to w+/n && Написать заголовок и дату @ 1,2 clear to 1,77 @ 1,4 say "Б И Б Л И О Г Р А Ф И Ч Е С К А Я К А Р Т О Т Е К А" ??replicate(" ",10),date() set color to n/rg use bibli && Открыть базу данных @16,2 to 23,50 && ПОМОЩЬ : @17,4 say "В РЕЖИМЕ РЕДАКТИРОВАНИЯ" @18,4 say "Esc - переход в меню. F1- просмотр примечаний" @19,4 say "PgUp,PgDn - перелистывание страниц" @20,4 say "Ctrl-Home - редактирование поля примечаний" @21,4 say "---------------------------------------------" @22,4 say "Шабаршин А.А. группа Р-410а май 1994 г" kk=0 && Начальные установки переменных nn=1 no=1 loc=.f. avt=.f. str=replicate(" ",14) strf=str go top && Установить указатель на первую запись do while nn#8 && Цикл пока не выбрано предложение меню ВЫХОД c=2 r=60 if nn#0 && Активизация меню @ c,r to c+9,r+17 double @ c+1,r+1 prompt " РЕДАКТИРОВАНИЕ " && nn=1 @ c+2,r+1 prompt " ДОБАВЛЕНИЕ " && nn=2 @ c+3,r+1 prompt " УДАЛЕНИЕ " && nn=3 @ c+4,r+1 prompt " ПЕЧАТЬ " && nn=4 @ c+5,r+1 prompt " ПОИСК " && nn=5 @ c+6,r+1 prompt " ФИЛЬТР " && nn=6 @ c+7,r+1 prompt " ИНДЕКСИРОВАНИЕ " && nn=7 @ c+8,r+1 prompt " ВЫХОД В ДОС " && nn=8 menu to nn endif 4 -------------------------------------------------------------------------------- if nn=0 nn=1 endif do case case nn=0 && Esc nn=1 case nn=1 &&--------------------- РЕДАКТИРОВАНИЕ nn=0 do while nn=0 @ 2,1 clear to 15,54 @ 3,2 say "Авторы " get name @ 4,11 get name2 @ 5,11 get name3 @ 7,2 say "Заглавие" get title @ 9,2 say "Язык оригинала" get lang @ 9,22 say "Город" get city @ 11,2 say "Издательство" get publ @ 13,2 say "Год издания" get year @ 13,19 say "Количество страниц" get page @ 15,2 say "Шифр" get cipher @ 15,19 say "Код" get code @ 15,35 say "Примечания" get rem @ c,r to c+9,r+17 read && Редактировать kk=readkey() && Получить код завершения режима редактирования do case case kk=12.or.kk=268 && Esc-возврат в меню nn=no no=1 case kk=7.or.kk=263 && PageDown-листать вниз (к концу) skip 1 if eof() && Проверка на конец файла go bottom && Перейти на последнюю запись endif case kk=6.or.kk=262 && PageUp-листать вверх (к началу) skip -1 if bof() && Проверка на начало файла go top && Перейти на первую запись endif case kk=36.or.kk=292 && F1-просмотр поля примечаний save screen && Запомнить экран @0,0 to 2,79 double @2,2 say " примечания:" set color to w+/n @3,0 clear to 24,79 @3,0 say "" ??rem ii=inkey(0) set color to n/rg restore screen && Восстановить старый экран endcase enddo 5 -------------------------------------------------------------------------------- case nn=2 &&--------------------- ДОБАВЛЕНИЕ append blank && Добавить в конец БД пустую запись go bottom && и переставить на нее указатель no=2 nn=0 case nn=3 &&--------------------- УДАЛЕНИЕ set color to w+/n rr=c+10 cc=r+3 @ rr,r clear to rr+4,r+17 @ rr+1,cc say " УДАЛИТЬ" @ rr+2,cc say " ЭТУ" @ rr+3,cc say "ЗАПИСЬ(Д/Н)?" @ rr+4,cc say " " ii=inkey(0) && Ожидание нажатия клавиши if ii=164.or.ii=132.or.ii=108.or.ii=76 && Проверка на Д,д,L,l ??"Да" delete && Пометить запись на удаление pack && Уничтожить помеченную запись else && Не уничтожать запись ??"Нет" endif set color to n/rg @ rr,r clear to rr+4,r+17 no=3 nn=0 case nn=4 &&--------------------- ПЕЧАТЬ save screen && Запомнить экран set printer on && Активизировать вывод на принтер set color to w+/n @ 0,0 clear to 24,79 ?" ----------------------------------------------------------------------------" ?"| БИБЛИОГРАФИЧЕСКАЯ КАРТОЧКА ",time()," ",date()," |" ?"|----------------------------------------------------------------------------|" ?"| Шабаршин А.А УГТУ-УПИ РТФ кафедра АИТ май 1994 |" ?" ---------------------------------------------------------------------------- " ?name,name2,name3 ?title ?"-",city,":",publ,",",year,".-",page,"c." ?"Язык оригинала:",lang,".Шифр:",cipher," Код:",code ?"Примечания:" ?rem set color to n/rg set printer off && Отменить вывод на принтер restore screen && Восстановить старый экран nn=0 no=4 6 -------------------------------------------------------------------------------- case nn=5 &&--------------------- ПОИСК zapold=recno() mm=1 c00=r-5 c1=r+17 r0=c+10 r1=r0+10 c0=c00+1 rr0=r0+1 cc0=c0 rr1=r1-1 cc1=c1-1 @ r0,c00 to r1,c1 double @ r0+1,c0 prompt " по автору " @ r0+2,c0 prompt " по названию книги " @ r0+3,c0 prompt " по языку оригинала " @ r0+4,c0 prompt " по издательству " @ r0+5,c0 prompt " по городу издания " @ r0+6,c0 prompt " по году издания " @ r0+7,c0 prompt " по коду " @ r0+8,c0 prompt " по шифру " @ r0+9,c0 prompt " ПОВТОРНЫЙ ПОИСК " menu to mm if mm#0 do case case mm=2 s="title" stt=.t. case mm=3 s="lang" stt=.t. case mm=4 s="publ" stt=.t. case mm=5 s="city" stt=.t. case mm=6 s="year" stt=.f. case mm=7 s="code" stt=.f. case mm=8 s="cipher" stt=.t. endcase 7 -------------------------------------------------------------------------------- if mm#9 @ rr0,cc0 clear to rr1,cc1 @ rr0+3,cc0 say " Введите строку для" @ rr0+4,cc0 say "поиска" get str read endif && Поиск автора по полям NAME,NAME2,NAME3 if mm=1.or.mm=9.and.avt loc=.t. avt=.t. if mm=1 locate for name=trim(str) fin=1 if eof() locate for name2=trim(str) fin=2 if eof() locate for name3=trim(str) fin=3 endif endif else do case case fin=1 continue if eof() locate for name2=trim(str) fin=2 if eof() locate for name3=trim(str) fin=3 endif endif case fin=2 continue if eof() locate for name3=trim(str) fin=3 endif case fin=3 continue endcase endif endif do case case mm=9.and.loc.and..not.avt continue case mm#9.and.mm#1 avt=.f. loc=.t. if stt locate for &s=trim(str) else locate for &s=val(trim(str)) endif endcase 8 -------------------------------------------------------------------------------- if eof() @ rr0,cc0 clear to rr1,cc1 @ rr0+3,cc0 say " ЗАПИСЬ НЕ НАЙДЕНА !" ??chr(7) ii=inkey(2) go zapold && Вернуть указатель на старую запись endif endif @ r0,c00 clear to r1,c1 && Стереть меню no=5 nn=0 case nn=6 &&--------------------- ФИЛЬТР mm=1 c00=r-5 c1=r+17 r0=c+10 r1=r0+9 c0=c00+1 rr0=r0+1 cc0=c0 rr1=r1-1 cc1=c1-1 ree=recno() @ r0,c00 to r1,c1 double @ r0+1,c0 prompt " по автору " @ r0+2,c0 prompt " по названию книги " @ r0+3,c0 prompt " по языку оригинала " @ r0+4,c0 prompt " по издательству " @ r0+5,c0 prompt " по городу издания " @ r0+6,c0 prompt " по году издания " @ r0+7,c0 prompt " по шифру " @ r0+8,c0 prompt " ОТМЕНИТЬ ФИЛЬТР " menu to mm if mm#0 if mm=8 && Отменить фильтр set filter to @ 23,c0 clear to 23,78 else @ rr0,cc0 clear to rr1,cc1 @ rr0+2,cc0+3 say "Введите фильтр" @ rr0+4,cc0+3 get strf read if strf=replicate(" ",14) mm=0 endif st=trim(strf) do case case mm=1 set filter to name=st.or.name2=st.or.name3=st case mm=2 set filter to title=st case mm=3 set filter to lang=st 9 -------------------------------------------------------------------------------- case mm=4 set filter to publ=st case mm=5 set filter to city=st case mm=6 set filter to year=val(st) case mm=7 set filter to cipher=st endcase @ 23,c0 say " ФИЛЬТР УСТАНОВЛЕН" endif go top if eof() && По такому фильтру база данных становится пустой @ rr0,cc0 clear to rr1,cc1 @ rr0+2,cc0 say " ТАКОЙ ФИЛЬТР" @ rr0+4,cc0 say " НЕУДАЧЕН !" ??chr(7) aa=inkey(2) set filter to go ree @ 23,c0 clear to 23,78 endif endif @ r0,c00 clear to r1,c1 no=6 nn=0 case nn=7 &&--------------------- ИНДЕКСИРОВАНИЕ mm=1 c00=r-5 c1=r+17 r0=c+10 r1=r0+10 c0=c00+1 @ r0,c00 to r1,c1 double @ r0+1,c0 prompt " по первому автору " @ r0+2,c0 prompt " по названию книги " @ r0+3,c0 prompt " по языку оригинала " @ r0+4,c0 prompt " по издательству " @ r0+5,c0 prompt " по городу издания " @ r0+6,c0 prompt " по году издания " @ r0+7,c0 prompt "по количеству страниц" @ r0+8,c0 prompt " по коду " @ r0+9,c0 prompt " по шифру " menu to mm if mm#0 && Уничтожить индексный файл close index erase bibli.idx endif do case && Установка индексов в зависимости от выбора case mm=1 index on name to bibli case mm=2 index on title to bibli case mm=3 index on lang to bibli case mm=4 index on publ to bibli case mm=5 index on city to bibli 10 -------------------------------------------------------------------------------- case mm=6 index on year to bibli case mm=7 index on page to bibli case mm=8 index on code to bibli case mm=9 index on cipher to bibli endcase go top @ r0,c00 clear to r1,c1 no=7 nn=0 endcase enddo quit && Выход в ДОС
Шабаршин А.А группа Р-410а 11 -------------------------------------------------------------------------------- ФУНКЦИОНАЛЬНЫЕ ЗАВИСИМОСТИ И ВОЗМОЖНЫЕ КЛЮЧИ
Имеется набор атрибутов :
NAME - первый автор книги NAME2 - второй автор книги (или строка пробелов) NAME3 - третий автор книги (или строка пробелов) TITLE - заголовок книги LANG - язык оригинала PUBL - издательство CITY - город издания YEAR - год издания PAGE - количество страниц CODE - библиотечный код CIPHER - тематический шифр REM - дополнительные сведения
Необходимо проследить функциональные зависимости между атрибутами. Атрибуты имен авторов ( NAME , NAME2 , NAME3 ) определяют только сами себя. Они не могут определять заголовок книги ( TITLE ), язык оригинала ( LANG ), издательство ( PUBL ), город издания ( CITY ), год издания ( YEAR ),количество страниц ( PAGE ), библиотечный код ( CODE ), тематический шифр ( CIPHER ) и дополнительные сведения ( REM ) потому-что вполне может существовать другая книга этих авторов , имеющая другой заголовок, написанная на другом языке, изданная в другом издательстве и другом городе в другом году, имеющая другое количество страниц , другой код библиотеки , написанная на другую тему и имеющая другие дополнительные сведения о себе. Атрибут заголовка ( TITLE ) определяет только самого себя и не может определять ничего другого, так-как другая книга может иметь тот-же заголовок. Не определют ничего кроме себя самих атрибуты языка оригинала ( LANG ), года издания ( YEAR ), количества страниц ( PAGE ),тематического шифра (CIPHER). Атрибут издательства ( PUBL ) определяет город издания ( CITY ) , т.е.
PUBL -> CITY (1)
Атрибут кода ( CODE ) определяет весь остальной набор атрибутов , так-как код книги отличает ее от всех остальных книг :
CODE -> {NAME,NAME2,NAME3,TITLE,LANG,PUBL,CITY,YEAR,PAGE,CIPHER,REM} (2)
Атрибут дополнительных данных ( REM ) функционально зависит от набора остальных атрибутов :
{NAME,NAME2,NAME3,TITLE,LANG,PUBL,CITY,YEAR,PAGE,CODE,CIPHER} -> REM (3)
Первичным ключом является атрибут кода ( CODE ).
12 -------------------------------------------------------------------------------- РЕАЛИЗАЦИЯ БОЛЬШЕГО КОЛИЧЕСТВА АВТОРОВ
В базе данных BIBLI использовалось три поля авторов. Для большинства случаев это много. Возможность заносить большее количество авторов, не увеличивая количества полей авторов, реализуется использованием второй базы данных BIBL_N :
1 NUM N 4 2 NAME C 20 В базе данных BIBLI вместо полей авторов введем два числовых поля :
1 NAME_B N 4 2 NAME_N N 2 ... ... .. ..
NAME_N - номер записи в базе данных BIBL_N, в которой хранится первый автор книги из текущей карточки. NAME_N - количество авторов этой книги. В данном случае NAME_B может принимать значения от 1 до 9999, а NAME_N от 0 до 99. Например :
BIBLI.DBF BIBL_N.DBF ----------------------- ------------------------------ N NAME_B NAME_N N NUM NAME ----------------------- ------------------------------ 1 0001 01 1 0001 Абель Питер 2 0002 03 2 0002 Ревунков Г.И 3 0003 Самохвалов Э.Н 4 0004 Чистов В.В 3 0005 01 5 0005 Страуструп Б. 4 0006 03 6 0006 Усатенко С.Т 7 0007 Каченюк Т.К 5 0008 00 (нет авторов) 8 0008 Терехова М.В
В этом случае можно реализовать все функции программы BIBLI:
1. РЕДАКТИРОВАНИЕ Обращение к базе данных авторов по указателю NAME_B , в этом случае редактируется только NAME_N записей БД авторов. Нужно предусмотреть меры по защите указателя NAME_B и количества авторов NAME_N от изменения иначе может возникнуть путаница. При необходимости изменить количество авторов в старой записи БД картотеки, следует реализовать следующий алгоритм : Так как авторы изменяемой карточки находятся в середине БД BIBL_N.DBF, то их количество уменьшается путем уменьшения NANE_N, при этом теряется одна или больше записей базы BIBL_N ,то есть на них ничто не ссылается. Потерянные записи можно стереть, причем индексы NUM уже не будут равны номерам записей:
N NUM NAME ---------------------------- 1 0001 Абель Питер 2 0002 Ревунков Г.И (от трех авторов остался один, NAME_N=1 ) 3 0005 Чистов В.В 4 0006 ... 13 -------------------------------------------------------------------------------- Если же требуется увеличение количества авторов, то уничтожаются все записи базы BIBL_N начиная с NAME_B в количестве NAME_N. В конце же базы данных организуется требуемое число (новое NAME_N) записей с новыми индексами NUM. При этом в записи карточки необходимо изменить и NAME_B. В результате этих операций возникают промежутки между индексами NUM в середине БД авторов BIBL_N.DBF . Возможно разработать механизм заполнения этих промежутков при организации новых карточек с подходящим количеством авторов путем добавления в конец базы BIBL_N записей с промежуточными индексами NUM и дальнейшей сортировкой файла BIBL_N.DBF по NUM.
2. ДОБАВЛЕНИЕ В общем случае при организации новой карточки в BIBLI.DBF полю NAME_B присваивается число NUM+1 из последней записи базы BIBL_N.DBF .
3. УДАЛЕНИЕ При удалении записи карточки из BIBLI.DBF в базе данных BIBL_N.DBF удаляются записи с индексами NUM от NAME_B до NAME_B+NAME_N-1 (NAME_N штук).
4. ПОИСК Поиск по авторам можно реализовать так : SET EXACT OFF SELECT 1 USE BIBLI SELECT 2 USE BIBL_N * Ввод строки для поиска STR STR=" ... " LOCATE NAME=STR NN=NUM && Присвоить индекс NUM SELECT 1 LOCATE NN>=NAME_B.AND.NN<NAME_B+NAME_N * Если .NOT.EOF() то карточка с таким автором найдена
Реализация повторного поиска, фильтрации и индексации возможна, но реализуется путем создания процедур-аналогов CONTINUE, SET FILTER и INDEX , что достаточно сложно.
| |