Информатика / лекции
.pdf9. Записной тип данных. СУБД |
221 |
Видно, что использование оператора присоединения избавило нас от необходимости каждый раз писать имя переменной SSS, к полям которой мы обращаемся. Это делает программный код более выразительным и наглядным.
9.2 Концепция БД
Если взять несколько переменных одинакового записного типа и начать с ними работать, то получится элементарная база данных.
База данных (БД) – это упорядоченная совокупность данных (и их описание), предназначенных для хранения, накопления и обработки с помощью ЭВМ.
Для создания и ведения базы данных (обновления, обеспечения доступа к ним по запросам и выдачи их пользователю) используется набор языковых и программных средств, называемых системой управления базы данных
(СУБД).
Наиболее естественное для понимания представление БД – это табличное. Самая простая БД – это БД состоящая из одной таблицы. Если таблиц больше чем одна и между ними установлены определенные связи, то такую БД называют реляционной (relation – англ. зависимость).
Рассмотрим пример реализации однотабличной БД. Пусть, например, таблица содержит описание магазинов (Таблица 9.1).
Таблица 9.1 Описание магазинов
|
|
|
Адрес (Adress) |
|
|
||
|
Реестр |
Название |
|
Дом |
Профиль |
Площадь, |
|
массив Base |
(Reestr- |
Улица |
магазина |
кв. м |
|||
(ShopName) |
(Number- |
||||||
Number) |
(Street) |
(SaleProfile) |
(Area) |
||||
|
|
OfBld) |
|||||
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
Base[1] |
1 |
Лимпопо |
Зеленая |
45 |
Детский |
320 |
|
|
|
|
|
|
|
|
|
Base[2] |
2 |
Хозяин |
Продоль- |
12 |
Хозяйственный |
140 |
|
ная |
|||||||
|
|
|
|
|
|
||
Base[3] |
3 |
Свежий |
Продоль- |
18 |
Продуктовый |
25 |
|
Хлеб |
ная |
||||||
|
|
|
|
|
|||
Base[4] |
4 |
Продукты |
Ленина |
123 |
Продуктовый |
60 |
|
|
|
|
|
|
|
|
|
Base[5] |
5 |
Все для |
Пушкина |
2 |
Хозяйственный |
75 |
|
ремонта |
|||||||
|
|
|
|
|
|
С точки зрения структуры записи удобно пользоваться иерархической диаграммой, изображенной на (Рисунок 9.1). Из диаграммы (как впрочем и из таблицы) видно что поле «Адрес» имеет сложную структуру (вложенная запись). Оно содержит поля «Улица» и «Дом». Здесь мы имеем дело с записным типом данных с пятью полями, одно из которых тоже записное, состоящее из двух подполей.
222 |
|
|
|
|
|
|
9.2 Концепция БД |
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Магазин |
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
(TShops) |
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Реестровый |
|
|
Название |
|
|
Адрес |
|
|
|
Профиль |
|
|
|
Площадь |
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||
|
номер |
|
|
|
|
|
|
|
магазина |
|
|
|
|
|||||||||||||
|
|
|
(ShopName) |
|
|
(Adress) |
|
|
|
|
|
|
(Area) |
|
||||||||||||
|
(ReestrNumber) |
|
|
|
|
|
|
(SaleProfile) |
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Улица |
|
|
|
Дом |
|
||
|
|
(Street) |
|
|
|
|
(NumberOfBld) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рисунок 9.1 Структура записи TShops, предназначенной для хранения информации о магазине
Важно понимать отличия Таблица 9.1 и диаграммы Рисунок 9.1. Суть этих отличий в том, что диаграмма содержит лишь структуру записи, а таблица уже конкретные примеры этой структуры. Выражаясь другим языком, можно сказать, что диаграмма – это тип переменной, а таблица – это множество значений переменной данного типа.
ПРИМЕР
На основе предложенной структуры сведений о магазине можно написать простую систему управления этими сведениями. К основным операциям управления отнесем операции создания описания магазинов, вывод таблицы со всеми сведениями на экран и выдачу информации о магазинах, удовлетворяющих определенным требованиям. Таковыми требованиями пусть будут определенный профиль магазина и площадь торгового зала, превышающая среднюю арифметическую площадей всех магазинов находящихся на данный момент в таблице.
Для начала в качестве инструмента хранения всех наших данных возьмем массив, т.е. напишем программу используя массив записей. Это означает, что каждый раз при запуске нам придется вводить все сведения о магазинах заново, ввиду того, что массивы хранятся в энергозависимой памяти и уничтожаются вместе с прекращением работы программы.
program subd; type
TShops = record ReestrNumber: integer; ShopName: string[10]; Adress : record
Street : string[15]; NumberOfBld : byte;
end; {Adress} SaleProfile : string[10]; Area : integer;
end; {TShops}
TBaseMass = array[1..255] of TShops;
224 |
9.2 Концепция БД |
Здесь приведен пример программного объявления типа записи изображенной на Рисунок 9.1. Далее идет объявление типа массива записей (TBaseMass) состоящего из TShops. В Таблица 9.1 показана возможная реализация массива описанного типа с именем Base. Соответственно, Base[i]
– отдельная компонента, включающая описание i-го магазина.
Далее идет объявление и описание процедуры для формирования нового массива записей InputNewBase. В качестве формальных параметров, как обычно у процедур для обработки массивов, выступает собственно сам массив и число компонент в нем. Блок-схема процедуры изображена на (Рисунок 9.2) а).
{процедура формирования новой таблицы} procedure InputNewBase(var Base:TBaseMass;
var NumOfRec:byte); var i: byte;
Shop: TShops; ContinueInput: char;
begin writeLn; i:=0; repeat
i:=i + 1; with Shop do
begin
write('Введите название ',i,'-го магазина: '); readLn(ShopName);
writeLn('Введите адрес магазина ',ShopName); write(' Улица: '); readLn(Adress.Street);
write(' Дом: '); readLn(Adress.NumberOfBld); write('Профиль магазина ',ShopName,': '); readLn(SaleProfile);
write('Площадь торговых площадей магазина
',ShopName,': '); readLn(Area);
write('Реестровый номер магазина ', ShopName,': ');
readLn(ReestrNumber);
end;
Base[i] := Shop;
writeLn('Вводим данные о следующем магазине'); writeLn('Если ввод окончен, то введите ''0'''); readLn(ContinueInput);
until ContinueInput='0'; NumOfRec:= i;
end;
9. Записной тип данных. СУБД |
225 |
Аналогично можно написать процедуру вывода элементов массива записей. Здесь стоит обратить внимание на использование оператора присоединения with объект do к пространству имен массива Base[i]. Это дает возможность обращаться к полям записи напрямую, минуя префикс “Base[i].”. Блок-схема этой процедуры представлена на (Рисунок 9.2) б).
{процедура вывода базы на экран} procedure OutBase(const Base:TBaseMass;
const NumOfRec:byte); var i,j: byte;
begin writeLn;
if NumOfRec <> 0 then begin
writeLn('База данных содержит следующие сведения:');
for j:=1 to 79 do write('-'); writeLn;
writeLn('N п/п':6,'| ','реестр. N |':11, 'Название |':12,'Адрес.Улица |':17, 'Дом |':7,'Торг. Профиль |':15, 'Площадь |':9);
for j:=1 to 79 do write('='); writeLn;
for i:=1 to NumOfRec do with Base[i] do
begin
write(i:5,' |'); write(ReestrNumber:10,' |'); write(ShopName:10,' |'); write(Adress.Street:15,' |'); write(Adress.NumberOfBld:5,' |'); write(SaleProfile:13,' |'); writeLn(Area:7,' |');
for j:=1 to 79 do write('-');
writeLn;
end; end
else
writeLn('БД пуста'); end;
Ниже представлена процедура, выдающая по запросу все магазины определенного профиля, площадь которых больше чем среднее арифметическое площадей всех магазинов данного профиля. Вначале идет подсчет среднего арифметического площадей магазинов удовлетворяющих
9. Записной тип данных. СУБД |
227 |
Шаг 1-2 (стр. XXX) Вывод записей удовл. запросу
SrA := SrA / k
Вывод SrA
Вывод заголовка |
|
|
таблицы |
|
|
i := 1 , NumOfRec |
Начало |
|
|
||
|
действия |
|
L |
пространства |
|
имен Base[ i ] |
||
Вывод i |
|
|
|
L := |
|
Вывод ReestrNumber |
(SaleProfile = |
|
NeedSaleProfile) |
||
|
||
|
and (Area ≥ SrA) |
|
Вывод ShopName |
|
|
Вывод Adress.Street |
|
|
Вывод |
|
|
Adress.NumberOfBld |
|
|
Вывод |
|
|
SaleProfile |
|
|
Вывод Area |
|
|
|
Окончание |
|
|
действия |
|
|
пространства |
|
|
имен Base[ i ] |
Рисунок 9.4 Детализация вывода к процедуре запроса
{Процедура обработки запроса к БД (поиск всех магазинов опр. профиля с площадью выше среднего)}
procedure RequestToBase(const Base:TBaseMass;
228 |
9.2 Концепция БД |
const NumOfRec: byte); var i,j,k: byte;
NeedSaleProfile: string[10]; SrA: real;
begin
if NumOfRec <> 0 then begin
writeLn;
writeLn('Обработка запроса: Все магазины
с площадью >= ср. арифметического');
writeLn;
write('Введите профиль магазина:'); readln (NeedSaleProfile);
SrA:= 0; k:=0;
for i:= 1 to NumOfRec do with Base[i] do
begin
If SaleProfile = NeedSaleProfile then begin
k:= k + 1;
SrA:= SrA + Area; end;
end;
if k<>0 then begin
SrA := SrA / k; writeLn('SrA = ', SrA:6:2);
writeLn('Вот результат запроса:'); for j:=1 to 79 do
write('-'); writeLn;
writeLn('N п/п':6,'| ','реестр. N |':11, 'Название |':12,'Адрес.Улица |':17, 'Дом |':7,'Торг. Профиль |':15,
'Площадь |':9); for j:=1 to 79 do write('='); writeLn;
for i:=1 to NumOfRec do with Base[i] do
if (SaleProfile = NeedSaleProfile) and (Area >= SrA) then
begin
write(i:5,' |'); write(ReestrNumber:10,' |'); write(ShopName:10,' |'); write(Adress.Street:15,' |');
9. Записной тип данных. СУБД |
229 |
write(Adress.NumberOfBld:5,' |'); write(SaleProfile:13,' |'); writeLn(Area:7,' |');
for j:=1 to 79 do write('-');
writeLn;
end;
end else
WriteLn('В базе нет магазинов профиля ', NeedSaleProfile);
end else
WriteLn('База данных пуста'); end;
Процедура вывода главного меню программы представлена реализацией оператора case, при помощи которого происходит выбор нужного действия. При вводе той или иной цифры происходит вызов соответствующей процедуры. Практически весь код процедуры помещен в цикл. Выход из этого цикла происходит после ввода цифры 4.
{процедура выводящая главное меню программы} procedure MainMenu;
var PunktOfMenu: byte; Base: TBaseMass; NumOfRec : byte;
begin
NumOfRec := 0; repeat
writeLn;
writeLn('Выберите нужное действие:'); writeLn('1 - Ввод новой БД'); writeLn('2 - Вывод БД');
writeLn('3 - Запрос к БД'); writeLn('4 - Выход'); write('Ваш выбор:'); readLn(PunktOfMenu);
case PunktOfMenu of
1:InputNewBase(Base, NumOfRec);
2:OutBase(Base, NumOfRec);
3:RequestToBase(Base, NumOfRec); else
if PunktOfMenu<>4 then
writeLn('Введите корректный пункт меню');
end; {конец case} until PunktOfMenu = 4 ;
end;