Смекни!
smekni.com

Бази даних у Internet (стр. 1 из 3)

Бази даних були природньо поєднані з WWW і CGI з самого початку Web. Фактично, Web є неосяжною всесвітньою базою даних, колекцією даних і ресурсів, доступних за допомогою клацання мишкою.

На вищому рівні, взаємодія з серверними базами даних є одним з найбільш природних застосувань CGI. Кінцевий користувач може представити запит через форму і мати результати, які показуються безпосередньо назад до його вікна перегляду.

Через те, що протягом транзакції з базою даних взаємодія у реальному часі звичайно не потрібна, однієї з головних перешкод CGI (відсутність постійного зв'язку) уникають одразу. Крім того, розмір бази даних майже не впливає на швидкість транзакції, тому що до клієнта посилаються тільки результати запиту. (Будь-хто, хто використовував один з пошуковиків Web, - наприклад, AltaVista або Lycos, може підтвердити це.)

Хоч будь-який вид бази даних доступний через CGI, є декілька типів баз даних, які стали дуже популярними на Павутині:

· Невеликі текстові бази даних. Вони є найлегшими для створення та корисними для багатьох малих або середніх задач. Ці бази даних є просто файлами ASCII з розмежуванням або записами фіксованої довжини. Адресні книги, списки, і такі інші бази даних з обмеженим рядом елементів добре відповідають вимогам саме цього методу.

  • Бази даних Web. Природніми кандидатами для баз даних Web є безпосередньо Web. Служби, які контролюють великі порції Павутини (наприклад, Usenet, Gopher, і так далі) виникають дуже часто. Це можна також застосувати до локальних мереж і єдиних машин. Індексне програмне забезпечення, подібне до freeWais або Ice може створити базу даних повного сайту, який потім буде доступний через програми CGI.
  • Великі серверні бази даних. Великі бази даних взагалі зберігаються в сервері деякої бази даних (навіть якщо сервер є також клієнт, як наприклад найбільш загальні базові бази даних Windows). Поки сервер має деякий інтерфейсний метод для інших програмам, інформація в цих базах даних буде доступна з програм CGI.

Практично, бази даних Web можуть бути деякою комбінацією вищевказаних. Кожна база даних має власні потреби, і програми CGI часто повинні бути налагодженими, щоб відповідати вимогам вашої конкретної бази даних.

Інтерфейси Баз даних

Для ефективного поєднання вашої бази даних з Web без будь-яких втрат, CGI повинен використовуватися як в інтерфейсі так і в реалізації взаємодії бази даних.

Інтерфейс CGI

Поперше, треба розглянути те, як користувач збирається ввести запити до бази даних. Форма HTML є найбільш загальним шляхом для користувача, щоб представити інформацію, хоч є і інші шляхи. Як приклад, розглянемо інтерфейс до адресної книги. Проста форма могла б бути схожою з цим:

<HTML><HEAD><TITLE>My Address Book</title></head>
<BODY>
<H2>Welcome to my address book</h2>
To find addresses that match a certain category, fill in that category and
then press 'submit'.
<FORM ACTION="address.cgi" METHOD="POST">
Name: <INPUT SIZE=45 name="name"><br>
Phone: <INPUT SIZE=45 name="phone"><br>
Street Address: <INPUT SIZE=45 name="street"><BR>
City: <INPUT SIZE=20 name="city"> State: <INPUT SIZE=3 name="state">
Zip: <INPUT SIZE=6 name="zip"><br>
<INPUT TYPE=SUBMIT Value=" Submit Query ">
<INPUT TYPE=RESET Value=" Reset Form "><br>
</body></html>

Ця форма викликає CGI-скрипт address.cgi. Це є інтерфейс взаємодії з базою даних. Намір інтерфейсу - забрати дані з форми, проаналізувати їх, і передати запит до бази даних. Якщо база даних є текстовим ASCII-файлом, інтерфейс є також і реалізацією. Він повинний зробити пошук, інтерпретувати дані, і потім передати результати назад до клієнта. Для серверів баз даних (включаючи такі індекси Web,як freeWais і Ice), інтерфейс повинний надати запиту форму, яку сервер зрозуміє, і потім передати запит до сервера. CGI-програма повинна потім забрати результати і передати їх до користувача. Дуже часто в цьому випадку інтерфейси і реалізації містяться в тій же програмі. На системах, які підтримують це (UNIX, Amiga, і інші), для цього можна застосовувати розгалуження процесу. У Windows-середовищі, необхідні спеціальні програми, які використовують OLE або деякий інший тип зв'язку.

Щоб повернутися до прикладу адресної книги, можна створити в даний момент програму CGI, яка відповість запиту клієнта.

По-перше, нам потрібно знати формат бази даних безпосередньо. Малий текстовий формат є достатнім для наших потреб. Ми повинні використовувати розмежовані дані, хоч записи фіксованої довжини повинні також працювати. Запис прикладу слідує:

0:Elmer J. Fudd:555-1234:42 Jones Lane:Chuckville:CA:90210

Цей формат буде добре обізнаний до будь-кого, хто бачив файл пароля UNIX. Є дві перешкоди до цього формату. Сума всіх полів не може перевищити ніяких обмежень лінійної довжини на будь-якій системі, яку ви використовуєте (в нашому випадку, це не має бути проблемою). Також, розділювач (двокрапка) не повинний з'являтися в будь-якому полі, або це буде сприйнято як початок нового поля. У ідеальному світі, це не повинне бути проблемою (, якщо не хто-небудь, хто живе за адресою "Нью-йорк: Місто"). Але фактично, люди роблять памылки. Таким чином, треба бути ознайомленим з цією потенційною проблемою.

Тепер, коли ми знаємо форму бази даних, ми можемо почати програму CGI, щоб зібрати інформацію від форми. Будь-яка мова може використатися для написання CGI, але в цьому прикладі використано Perl для використання можливостей обробки тексту.

#!/bin/perl

require cgi_head; # Дістати дані з форми та роздрукувати заголовок.

!!!!!
У всіх CGI, написаних на Perl в цьому розділі, модуль cgi_head.pm використовується, для збору інформації від форми і надрукувати необхідний заголовок HTML. Цей модуль розміщує вхід форми з ім'ям 'foo' в асоціативний вхід з ім'ям $FORM{'foo'}. Існує декілька вільнодоступних програм для декількох мов, для виконання цього, включаючи CGI.pm для Perl : http://www.perl.com/perl/CPAN/

Тепер, коли дані з форми були прочитані, треба прочитати записи в базі даних безпосередньо. Через те, що ми використовуємо розмежовану базу даних, найлегше прочитати з повної бази даних. База даних поля фіксованої довжини повинна дати нам можливість просуватися через базу даних без читання інформації, але цей метод має власні перешкоди (найбільш очевидне те, що дані не повинні перевищувати незмінну довжину). Ми читаємо базу даних, як плаский ASCIІ-файл і аналізуємо це полінійно, використовуючи зручну Perl-конструкцію while(<FILEHANDLE>)<>.

!!!!!
Цей приклад вимагав Perl 5.001 або вище, через використання звертань, які не включалися в Perl 4 (або раніше). Perl 5 містить багато покращень та нових можливостей і є необхідним для будь-якого Перломану -доступний на http://www.perl.com/perl/CPAN/<>

# Спершу, відкрийте базу даних. (тут 'database.txt'.)
open (DAT, "database.txt") || die "Can't open the database: $! !.&bsol;n";
$maxn = 0; # лічильник записів.
while (<DAT>) {
chop;
@field = split(/:/); # розбити запис на окремі поля
$n = $field[0]; # Перше поле є ID номером
$add[$n]{'name'} = $field[1]; # Потім ім'я
$add[$n]{'phone'} = $field[2]; # тел. номер
$add[$n]{'street'} = $field[3]; # адреса
$add[$n]{'city'} = $field[4]; # місто
$add[$n]{'state'} = $field[5]; # країна
$add[$n]{'zip'} = $field[6]; # поштовий індекс
}
$maxn = $n # Встановлено max номер до останнього запису

Тепер, коли база даних була завантажена, нам потрібно порівняти запит користувача з даними :

@results = (); # обнулити вихідний масив.

if ($name = $FORM{'name'}) { # пошук за ім'ям,
for ($I = 0; $I <= $maxn; $I++) { # пройти по всіх записах
if ($name eq $add[$I]{'name'}) { # шукаючи співпадань.
push(@results,$I); # якщо найдено, додати номер }
if (!@results) { &exitnone; } # якщо нічого не знайдено - вийти.
}
# Тепер для кожного критерію. Якщо є результати від попереднього
# пошуку, шукати в них, і видалити будь-які невідповідні записи.

if (($phone = $FORM{'phone'}) && !@results) {
for ($I = 0; $I <= $maxn; $I++) {
if ($phone eq $add[$I]{'phone'}) {
push(@results,$I);
}
}
if (!@results) { &exitnone; }
} elsif ($phone = $FORM{'phone'}) {
@r2 = @results;
foreach $I (@r2) {
if ($phone ne $add[$I]{'phone'}) {
@results = grep(!/$I/,@results);
}
}
if (!@results) { &exitnone; }
}

if (($street = $FORM{'street'}0 && !@results) {
for ($I = 0; $I <= $maxn; $I++) {
if ($street eq $add[$I]{'street'}) {
push(@results,$I);
}
}
if (!@results) { &exitnone; }
} elsif ($street = $FORM{'street'}) {
@r2 = @results;
foreach $I (@r2) {
if ($street ne $add[$I]{'street'}) {
@results = grep(!/$I/,@results);
}
}
if (!@results) { &exitnone; }
}

if (($city = $FORM{'city'}) && !@results) {
for ($I = 0; $I <= $maxn; $I++) {
if ($city eq $add[$I]{'city'}) {
push(@results,$I);
}
}
if (!@results) { &exitnone; }
} elsif ($city = $FORM{'city'}) {
@r2 = @results;
foreach $I (@r2) {
if ($city ne $add[$I]{'city'}) {
@results = grep(!/$I/,@results);
}
}
if (!@results) { &exitnone; }
}

if (($state = $FORM{'state'}) && !@results) {
for ($I = 0; $I <= $maxn; $I++) {
if ($state eq $add[$I]{'state'}) {
push(@results,$I);
}
}
if (!@results) { &exitnone; }
} elsif ($state = $FORM{'state'}) {
@r2 = @results;
foreach $I (@r2) {
if ($state ne $add[$I]{'state'}) {
@results = grep(!/$I/,@results);
}
}
if (!@results) { &exitnone; }
}

if (($zip = $FORM{'zip'}) && !@results) {
for ($I = 0; $I <= $maxn; $I++) {
if ($zip eq $add[$I]{'zip'}) {
push(@results,$I);
}
}
if (!@results) { &exitnone; }
} elsif ($zip = $FORM{'zip'}) {
@r2 = @results;
foreach $I (@r2) {
if ($zip ne $add[$I]{'zip'}) {
@results = grep(!/$I/,@results);
}
}
if (!@results) { &exitnone; }
}

У цей момент, або ми маємо успішні співпадання, які зберігаються в масиві @results, або ми не маємо співпаданнь, і в цьому випадку ми викликаємо підпрограму &exitnone. Тепер ми можемо видати клієнту результати (або їх відсутність).

# якщо немає результатівБ видати повідомлення та вийти.

sub exitnone {
print <<EOE;
<HTML><HEAD><TITLE>No matches</title></head>
<BODY>

<h3>There were no matches that fit your criteria.</h3>
<A HREF="addrbk.html">Go</a> back to the form to try again.
</body></html>
EOE

die;
}

# роздрукувати результати.

print <<EOP;
<HTML><HEAD><TITLE>Search Results</title></head>
<BODY>
<h3>The entries that matched your search</h3>
<pre>
EOP

foreach $r (@results) {
print <<EOG;

----
Name: $add[$r]{'name'}
Phone: $add[$r]{'phone'}
Address:
$add[$r]{'street'}
$add[$r]{'city'}, $add[$r]{'state'} $add[$r]{'zip'}

EOG

}
print <<EOH;
</pre><br>
Thank you for using my address book.
<A HREF="addrbk.html">Go</a> back to the form to make another search.
</body></html>
EOH

Тепер ми маємо робочий інтерфейс до адресної книги. Є декілька оптимізацій, які могли б бути зроблені, але це помітно лише для декількох дюжин записів. Зверніть увагу, що цей скрипт робить тільки логічний пошук AND на всіх полях. Можливо зробити OR-пошук - через знищення всіх викликів до &exitnone, крім останнього. Таким чином, коли програма не знаходить ніяких співпадань, вона не скінчиться, а перейде до наступного поля. Можна, також дати кінцевому користувачеві можливість вибрати, чи зробити пошук AND або OR за допомогою додавання спадного меню до сторінки форми. Тоді CGI міг би вийти або ні залежно від вибору.