Что такое база данных
Реализация доступа к базе данных на Perl
Пример реализации
Просмотр
Формат базы данных
Поиск - db.search.cgi
Просмотр записей базы данных - db.view.cgi
Редактирование записей - db.edit.cgi
Заключение

Глоссарий

Где найти


Описывается система, позволяющая вести в Web базу контактной информации для бизнеса. Для ее реализации потребуются Perl версии 5, DB-1.85 (или 1.86) и библиотека libwww-perl - все это свободно распространяемые программные продукты. Примеры писались в расчете на Unix, однако DB и Perl существуют также в версиях для NT.

Днем я профессиональный разработчик Web-узлов, а вечером, когда отложу мышь, превращаюсь в энтузиаста-велосипедиста. Будучи абсолютно неспособным разделить свою жизнь на профессиональную и частную, я на самой заре WWW создал официальный Web-узел Международной ассоциации по велосипедам и веломобилям (IHPVA - International Human Powered Vehicle Association).

Управлять вручную большим Web-узлом - ни с чем не сравнимое удовольствие. Конечно, это и немалый труд, но когда вы предоставляете услуги, которых нигде больше не найти, поддержка и благодарность посетителей узла не иссякают.

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

Пока же я решил построить систему, которая будет позволять посетителям моего узла самим добавлять ссылки, заполняя специальную форму. Эта идея, конечно, довольно наивна, но я готов рискнуть, чтобы проводить больше времени на невообразимых экспериментальных велосипедах и меньше - на сервере (см. http://www.ihpva.org/people/bwilson/cyclodine/).

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

Ассоциация IHPVA - небольшая бесприбыльная организация. Финансовые средства на этот проект не выделены, поэтому применение коммерческих СУБД исключается. Для поддержки форм используются сценарии на языке Perl, для обслуживания базы - совместимая с Perl бесплатная система Berkeley DB (при желании можно заменить ее на разработанную в рамках проекта GNU систему GDBM).

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

Что такое база данных

Файловые системы Unix и NT просты. В деталях они различаются, но обе ориентированы на доступ к файлу как к потоку байтов. Их можно сравнить с магнитной лентой. Вы открываете файл и читаете его, при этом лента движется вперед. Ее можно перемотать вперед или назад, вызвав функцию seek. Добавляемые данные обычно записываются в конец файла; чтобы вставить их в середину, нужно переписать всю информацию в новый файл, а старый уничтожить.

Как видим, все очень просто, но в результате определенные операции, такие как вставка, сортировка или поиск данных, отнимают слишком много времени. Чтобы их ускорить, выдающиеся умы из Беркли выдумали базу данных DB.

Система DB надстраивается над файловой системой и обеспечивает эффективный произвольный доступ к данным. Все базы данных семейства DB (DB, GDBM и более ранняя DBM) поддерживают так называемое хеширование. Данные хранятся как записи, индексированные по ключу. Ключи разных записей не должны совпадать; на их основе с помощью специальной хеш-функции DB строит адрес в файле, также не совпадающий ни с каким другим.

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

Кроме того, Berkeley DB поддерживает базы данных на основе B-деревьев. При использовании B-деревьев новые записи вносятся в базу таким образом, что она всегда остается рассортированной. Работа с хешированием и с B-деревьями на Perl одинаково тривиальна. Здесь я пользуюсь хешированием, так как оно больше подходит для моей задачи.

Если ваши потребности просты, то вам вполне подойдет Berkeley DB. С ней легко работать, она надежна и, что весьма важно, бесплатна.

Реализация доступа к базе данных на Perl

Для открытия и закрытия файлов формата DBM в Perl 4 применяют функции dbmopen() и dbmclose(). Ими можно пользоваться и в Perl 5, но в нем есть также функции tie и untie, позволяющие работать с рядом различных типов файлов и методов доступа.

В Perl встроена поддержка хеш-массивов (или, как их еще называют, ассоциативных массивов). Тем, кто незнаком с соответствующими конструкциями, видимо, следует заглянуть в руководство по языку. Функция tie сообщает Perl, что данный хеш-массив следует связать с файлом, функция untie разрывает связь. Они работают аналогично функциям открытия и закрытия файла, но когда хеш-массив связан с файлом базы данных, вы можете работать с файлом как с массивом, не задумываясь о том, что в действительности читаете с диска и записываете на диск.

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

Листинг 1. Связывание хеш-массива с файлом

use DB_File;    # Пакет для доступа к файлам DB
use Fcntl;      # Определения констант для O_RDWR 
# и дружественных классов

$dbfile = /tmp/datafile.db ;    # Имя файла данных
$key    = wilson,brian ;                # Ключ

tie %mydata, DB_File, $dbfile, O_RDWR|O_CREAT, 0664, $DB_HASH;

$mydata{$key} = "Write this data into the database file.";
# Содержание записи - текст 
# "Записать эти данные в файл базы данных".

# Для каждой записи вывести ключ и содержимое.
foreach (keys %mydata) {
    print "$_ = $mydata{$_}
";
}

delete($mydata{$key});  # Удалить только что 
# добавленную запись.

untie %mydata;

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

Заметьте также, что в базу можно поместить любые данные. Структура записи не задается; упаковка и распаковка записей оставляются на усмотрение прикладной программы. Это, конечно, усложняет ее по сравнению с аналогичной программой для более продвинутой СУБД, но зато позволяет создавать очень гибкие системы.

Один из наиболее сложных моментов в работе с файлами DB - это задание строки для связывания. Дополнительные указания вы сможете найти в документации Perl в статьях AnyDBM_File и DB_File (задайте команду perldoc AnyDBM_File). Перед тем как использовать строку для связывания в полноценной CGI-программе, напишите тест длиной в 5-10 строк и посмотрите, как он работает.

Разберем строку для связывания, использованную в нашем примере. Она имеет следующий вид:

tie %mydata, DB_File, $dbfile, O_RDWR|O_CREAT, 0664, $DB_HASH;

tie - это, как вам уже известно, имя функции;

%mydata - это хеш-массив, с которым функция tie должна связать файл;

параметр DB_File сообщает интерпретатору Perl о том, что будет использоваться пакет DB_File;

$dbfile - это строка, содержащая имя файла;

O_RDWR|O_CREAT - это двоичные флажки, которые сообщают функции открытия базы данных, каким образом открывать файл; в данном случае он открывается для чтения и записи, а если не существует, то создается.

0664 - это набор прав доступа к файлу, используемый в случае, когда файл создается;

параметр $DB_HASH сообщает пакету DB_File, что с данным файлом должно использоваться хеширование.

У флажков, задающих способ открытия файла, есть еще полезное значение O_RDONLY, при котором файл базы данных читать можно, а изменять - нет. Программистам, работающим на Си, эти флажки покажутся знакомыми: точно такие же используются с функцией open() этого языка. Чтобы получить полный список всех доступных флажков открытия, посмотрите справку (man) по функции open().

Сейчас мы рассмотрим общую организацию нашей системы, а затем - некоторые детали "закулисной" работы Perl, благодаря которой эта система может функционировать.

Пример реализации

База контактной информации разделена на две секции. Секция ввода позволяет пользователям с соответствующими правами доступа (а в нашей демонстрационной версии - кому угодно) непосредственно просматривать и редактировать записи базы данных. Когда запись откорректирована, запускается программа Webgen, которая строит из баз данных статические Web-страницы.

Секция просмотра состоит из полученных в результате работы Webgen статических страниц; в стандартном случае она представляет собой единственную область, открытую для всеобщего доступа.

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

Для всего этого служат три CGI-программы (сценария).

1. Программа db.search.cgi принимает (используя метод запроса GET) поисковую строку QUERY_STRING и производит поиск в базе. Результат ее работы - страница ссылок на db_view.cgi со встроенным текстом запроса, выводящих пользователя прямо в форму ввода данных. Иными словами, типичная ссылка имеет вид

wilson.brian

2. Программа db.view.cgi принимает строку запроса GET и анализирует форму HTML, которая называется db.form.html, вставляя в ее поля значения соответствующих полей из записи базы данных. Если в запросе задано слово new, она возвращает незаполненную форму ввода, а если параметр QUERY_STRING отсутствует - индекс базы данных, где на каждый ключ сделана ссылка со встроенным запросом.

3. Программа db.edit.cgi вызывается из формы db.form.html. Реально в db.form.html содержатся две формы; это сделано, чтобы обеспечить работу двух кнопок: одна будет использоваться для добавления и изменения записей, вторая - для их удаления. db.edit.cgi обрабатывает запросы от обеих кнопок, соответствующим образом модифицируя базу.

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

В сценариях используются также некоторые средства, предоставляемые общедоступными библиотеками, а конкретно - модулями libwww-perl и html.pm.

Чтобы ввести запись, необходимо:

  • произвести поиск в базе и убедиться, что такой записи в ней нет;
  • извлечь старую запись и изменить ее либо создать новую;
  • сгенерировать новые Web-страницы для просмотра.
  • Для поиска можно либо ввести запрос, либо вызвать полный индекс и просмотреть его. Обратите внимание на то, что команды поиска и вызова индекса относятся к секции ввода, а не просмотра. Ссылки на странице результатов в обоих случаях направляют пользователя непосредственно в форму ввода данных.

    Форма позволяет ввести базовую информацию об имени и адресе и, если нужно, об адресе электронной почты и URL. В качестве ключа используется поле названия фирмы. (Таким образом, для каждой фирмы можно держать в базе не более одной записи; это, конечно, не годится в случае реальной базы.)

    Как владелец базы я должен знать, когда она модифицировалась, и поэтому в программе db.edit.cgi предусмотрена функция, которая при каждом запуске отправляет мне по электронной почте соответствующее извещение. На случай хулиганских выходок (например, кто-то возьмет и удалит все записи) я храню резервную копию базы.

    Просмотр

    Совершенно отдельно от секции ввода данных существует набор генерируемых из базы Web-страниц. Это статические страницы: после того, как они сгенерированы, обращение к базе не происходит. Такое решение позволяет, во-первых, уменьшить загрузку процессора, а во-вторых, предоставить пользователям индексные страницы (чтобы построить индекс, нужно обратиться к каждой записи базы - вряд ли разумно заставлять сервер делать это всякий раз, как кто-то зайдет на индексную страницу).

    Как же строятся эти страницы? В компании ILC, где я работаю, сейчас разрабатывается версия нашей программы Webgen на языке Perl, и для этой статьи я сделал ее версию с сокращенным набором функций, которая называется perlgen.

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

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

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

    В построении на основе базы WWW-страниц замечательно то, что, решив позже добавить еще какой-то индекс, я смогу сделать это, просто написав новый шаблон для Webgen, - заново вводить данные не потребуется. Формат индивидуальных страничек записей тоже легко в любой момент изменить (например, подставить в них новую карту переходов). Для этого можно использовать и серверный оператор include, но тогда возникнет дополнительная нагрузка на сервер.

    Оставшаяся часть статьи будет посвящена реализации секции ввода данных.

    Формат базы данных

    Итак, мы обсудили, что нам нужно делать с данными. Теперь необходимо решить, как их хранить. Здесь в игру вступают противоречащие друг другу требования: невозможно добиться одновременно и гибкости, и удобства, и компактности хранения данных.

    Общепринятый метод сжатия и обработки данных заключается в преобразовании их в двоичную форму. Рассмотрим для каждого поля множество всех его допустимых значений. Если их не слишком много, каждому можно сопоставить целое число из довольно узкого диапазона и отвести на представление поля соответствующее число битов. Например, поле state (штат) может принимать всего 50 различных значений (по числу штатов в США), поэтому для его представления достаточно 6 бит (диапазон 0-64).

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

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

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

    Записи базы данных DB состоят из двух частей: ключевого поля, используемого для поиска, и значения.

    На языке Си записи естественнее всего было бы описывать как структуры. В Perl организовать аналогичную обработку данных можно с помощью функций pack и unpack, но мне этот способ кажется слишком громоздким. И поскольку система работает с Web, я решил хранить записи в строковой форме, применяя для кодирования формат GET. Это позволит использовать при кодировании и декодировании подпрограммы из модуля URI.

    Ключом в нашем примере служит название фирмы. Значение состоит из данных, заносимых в форму, и пакуется вместе с ключом.

    Вспомним, что метод запроса GET делает это сам; используемая форма записи следующая:

    переменная1=значение1&переменная2=значение2&переменная3=значение3

    (Строки этого вида иногда появляются в окнах браузеров в поле URL после самого URL.)

    Итак, формат поля - имя переменной, знак равенства и данные. Поля соединяются амперсандами. Специальные символы (знак равенства, амперсанд, пробел) представляются в данных escape-последовательностями, состоящими из знака процента и шестнадцатеричного кода символа. Например, запись, содержащая мое имя, фамилию и телефон, будет храниться в такой форме:

    name=Brian%20Wilson&phone=415%20575%201156

    Сценарий на Perl анализирует запись; сначала он разбивает ее на поля (по амперсандам), затем отделяет имена полей от значений (по знакам равенства). Для преобразования специальных символов я использовал модуль URI:Escape из библиотеки libwww. Нужные подпрограммы называются uri_escape (преобразование ASCII-символов в escape-последовательности) и uri_unescape (обратное преобразование).

    Представление информации в виде пар переменная=значение обеспечивает абсолютно свободную форму базы данных. Чтобы добавить в форму поле или изъять его оттуда, не нужно вообще никаких изменений в программе. Мы платим за это удобство перерасходом памяти и времени (дополнительное время тратится на упаковку и распаковку), и я не советовал бы применять описанный способ хранения записей для большой и сложной базы. Однако для нашей базы контактной информации он вполне подходит.

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

    Если вы прочтете мою статью о программировании на Perl в майском номере NetscapeWorld (Brian Wilson. How to write Perl & CGI scripts you can reuse again & again. http://www.netscapeworld.com/nw-05-1997/nw-05-perl.html), то заметите, что здесь я применяю такой же подход, как и там: три не зависящих друг от друга CGI-программы считывают конфигурационную информацию из общего файла под названием db.config. Благодаря этому их можно настраивать как единый пакет.

    Поиск - db.search.cgi

    В форме для поиска имеется кнопка, которая позволяет включать и отключать режим "только ключи". Когда этот режим включен, при поиске просматриваются только ключевые поля, когда отключен - записи полностью. Основной код db.search.cgi приведен в листинге 2.

    Листинг 2. Поиск в базе данных

        while (($k,$v) = each(%db)) {
            next if $k eq '';       # Пропустить пустой ключ
    
            $match = grep(/$query/i, $k);   # Искать в ключе
    
            if (!$opt_k && !$match) {       # Если не задан
    # поиск только в
                $match = grep(/$esc/i, $v); # ключе, искать по
    # всей записи
            }
    
            if ($match) {
                $count++;
                $uri = uri_escape($k);
                print "$count $k
    "; } }

    Комментарий:

    %db - это хеш-массив, связанный с базой данных DB, а оператор while задает просмотр этого массива с помощью функции each(), возвращающей для каждой записи ключ и значение. Для поиска строки запроса внутри ключа (и, если заказан соответствующий режим, внутри всей записи) используется функция grep языка Perl.

    Всякий раз, когда функция grep обнаруживает совпадение, оператор print выводит ссылку, по которой будет активизирована CGI-программа $VIEWER, выдающая на экран форму редактирования с соответствующей записью. Определение $VIEWER содержится в файле db.config.

    Оставшаяся часть программы db.search.cgi обеспечивает главным образом извлечение информации из переменной окружения QUERY_STRING, переданной браузером из поисковой формы, и возврат страницы с сообщением о неудаче поиска.

    Просмотр записей базы данных - db.view.cgi

    Сценарий db.view.cgi выполняет две функции: во-первых, выводит на экран чистую или заполненную форму ввода данных, во-вторых, выводит полный индекс базы.

    В начале работы сценарий проверяет, передана ли ему строка запроса. Если нет, происходит переход к выводу индекса.

    Основной код генератора индекса имеет вид:

    foreach $key (sort keys %db) {
    $uri = uri_escape($key);
    print "$key
    ";
    }

    В этом случае применен foreach-цикл, поскольку результат должен быть рассортирован по ключу. Конечно, в db.search.cgi тоже хорошо было бы выдавать рассортированный список, но функция each несколько эффективнее; кроме того, мне хотелось продемонстрировать оба способа перебора записей.

    Фрагмент программы, ответственный за построение заполненной формы, приведен с некоторыми сокращениями в листинге 3.

    Листинг 3. Построение заполненной формы

        if ($query) {
    
            @fields = split /&/, $db{$key};
    
            return 0 unless @fields;
    
            # Переместить все поля записи в хеш-массив FORM,
            # чтобы их можно было вставить в форму HTML.
    
            $FORM{$KEY} = $key;
            foreach (@fields) {
                ($k,$v) = split /=/;
                $FORM{$k} = uri_unescape($v);
            }
        }
    
        if (open(FILE, "<$form")) {
    
            undef $/;     # Выключить обработку перехода на 
    # новую строку
            $_ = ;  # Скопировать весь файл в $_
            close FILE;
            s/"/"/g; # escape-последовательность для 
    # кавычек
            s/@/@/g; # escape-последовательность для 
    # специальных знаков
    
            print "Content-type: text/html
    
    ";
    
    # Функция eval переносит значения из хеш-массива %RECORD
    # в специальную форму, которая отсылается обратно.
            print eval ""$_"";

    В секции if ($query), если программе был передан запрос, запускается поиск в базе данных, если нет - строится незаполненная форма для ввода новой записи. В секции if (open...) файл db.form.html считывается в переменную $_.

    Некоторая хитрость здесь заключается в файле db.form.html. Типичное поле ввода в нем выглядит примерно так:

    Последний оператор - print - содержит обращение к функции eval, по которому интерпретатор Perl проанализирует содержимое переменной $_, развернув переменную $FORM{city}. Таким образом, если соответствующая запись базы данных содержит значение для поля city, оно появится в форме, сгенерированной оператором print программы db.view.cgi. Оцените подход!

    Редактирование записей - db.edit.cgi

    Программа редактирования записей прежде всего проверяет ключ. При отсутствии правильного ключа выводит страничку с сообщением об ошибке, предлагающим пользователю нажать кнопку возврата на предыдущую страницу. Затем программа выясняет, не состоит ли строка запроса из слова delete (удалить). Если это так, в файл db.form.html добавляется вторая форма вызвавшей страницы, содержащая только действие и кнопку подтверждения с надписью delete.

    Получив запрос на удаление, db.edit.cgi удаляет соответствующую запись из базы данных. Код на языке Perl, позволяющий это сделать, очевиден: delete $db{$key}. Между прочим, каждая операция, которую выполняет db.edit.cgi, сопровождается посылкой по электронной почте сообщения администратору Web-узла, т. е. мне. Так что если какой-нибудь социально не адаптированный тип удалит из базы все записи, я сразу же узнаю об этом и восстановлю базу по резервной копии.

    Основная операция здесь связана с записью информации, которая была введена в форму, в базу данных DB. После добавления или изменения каких-либо записей вызывается программа Webgen, ответственная за построение статических Web-страниц (в случае удаления она должна убрать соответствующую ссылку с индексной страницы).

    Основная часть функции modify_record показана в листинге 4.

    Листинг 4. Модификация записи

    # - Упаковать в строку данные из формы -
    
        $FORM{modtime} = time;
    
        while (($k, $v) = each(%FORM)) {
            $record .= '&' if $flag++;
            $record .= $k . '=' . uri_escape($v);
        }
    
    # - Записать строку в базу данных -
    
        $k = $FORM{$KEY};
        $db{$k} = $record;
        send_mail("Database record '$k' has been modified.
    
    $record");
    
    # Содержание сообщения: запись базы данных с ключом $k
    # была изменена и теперь имеет вид $record.

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

    Затем программа последовательно перебирает поля формы и присоединяет их к строке $record. Обратите внимание на вызов функции uri_escape, которая перед помещением в строку очищает значение поля от возможных специальных символов.

    Когда строка записи построена, строка $record заносится в хеш-массив %db по ключу, который определяется переменной $KEY, описанной в файле db.config. Хеш-массив, как мы помним, связан с файлом базы данных.

    И наконец, программа отправляет по электронной почте сообщение, что позволяет мне следить за событиями. Функция send_mail определена в модуле db.edit.cgi и вызывает Unix-команду sendmail.

    Дальнейшие действия после возврата в основную секцию будут заключаться в построении страницы с благодарностями, вызове программы Webgen и создании ссылки на только что построенную этой программой страницу - так, чтобы туда можно было сразу же перейти.

    Заключение

    Для поддержки несложных прикладных систем, таких как описанная здесь база контактной информации, не нужны сложные реляционные СУБД. Необходимый набор возможностей легко обеспечит любая из трех свободно распространяемых реализаций DB (в том числе SDBM, входящая в состав пакета Perl). Осваивать вам потребуется только функцию tie; все прочее ничем не отличается от работы с хеш-массивом, находящимся в памяти.


    Брайан Уилсон работает программистом в компании ILC (Internet Literacy Consultants) в Сан-Франциско (шт. Калифорния), которая занимается различными консалтинговыми услугами в области Internet.
    E-mail: brian.wilson@netscapeworld.com.

    Глоссарий

    ассоциативный массив (associative array)
    см. хеш-массив.

    встроенный запрос (embedded query)
    в этой статье - ссылка, в которую вставлена строка запроса; при щелчке по такой ссылке запускается CGI-сценарий, которому с помощью оператора GET передается запрос. С точки зрения пользователя это ничем не отличается от загрузки другой страницы, но в действительности эта страница строится CGI-программой динамически в результате обработки запроса.

    хеш-массив (hash)
    (другое название - ассоциативный массив) в языке Perl, массив, в котором каждый элемент индексируется строкой. Название "хеш-массив" связано с тем, что адрес элемента в памяти вычисляется хеш-функцией.

    хеш-функция (hash function)
    функция, принимающая на входе набор ключей и генерирующая для каждого уникальное целое число, которое может использоваться как смещение при хранении связанных с этим ключом данных в массиве. В Perl устройство этой функции скрыто от программиста.

    B-дерево (B-tree)
    структура данных, организованная как дерево, благодаря чему при добавлении нового элемента список элементов остается упорядоченным.

    CGI (Common Gateway Interface - единый интерфейс шлюзов)
    спецификация для сценариев, которые должны выполняться на Web-сервере. Такие сценарии называют CGI-сценариями или CGI-программами.

    CPAN (Comprehensive Perl Archive Network - сеть полного архива Perl)
    группа дублирующих друг друга Web-узлов с грандиозным собранием модулей и расширений для Perl.

    DB, DBM, GDBM
    в этой статье под DB понимается пакет для работы с базами данных, созданный в Калифорнийском университете в Беркли как часть разрабатывавшейся там версии Unix. Пакет DB называют "новым", в отличие от входящего в состав некоторых версий Unix "старого" пакета DBM. В составе Linux имеется пакет GDBM, разработанный в рамках проекта GNU. В настоящее время DB - самый совершенный из трех пакетов, поскольку он поддерживает и B-деревья, и обычные файлы, и хешированные файлы. GDBM работает только с хешированными файлами. И DB, и GDBM лучше, чем DBM, которая накладывает ограничения на размер записей и занимает больше места на диске.

    GET и POST
    Оператор GET передает входную последовательность CGI-программе через переменную окружения. Оператор POST делает то же самое через стандартный вывод. Подробности можно найти в книге Clinton Wong. Web Client Programming with Perl (http://www.amazon.com/exec/obidos/ ISBN=156592214X/netscapeworldA/).

    Perl
    язык для настоящих программистов.

    QUERY_STRING
    имя переменной окружения, которой Web-сервер присваивает значение при передаче информации CGI-программе с помощью оператора GET.


    Где найти

  • Исходные тексты сценариев и форм, о которых рассказывается в этой статье:
    http://www.netscapeworld.com/nw-07-1997/PerlDB/linkomatic.tar.gz
    Тексты представляют собой tar-архив, сжатый методом gzip.
    Командой gunzip -c | tar xf распакуйте его в каталог с названием linkomatic. Дальнейшие инструкции вы найдете в файле README.
  • Berkeley DB
    http://mongoose.bostic.com/db/
  • Архив Perl (включая модуль libwww-perl)
    http://www.perl.com/CPAN/
  • Базовая страница проекта GNU
    http://www.gnu.org/