HTML page

Глава 14 Базы данных

Базы данных

Введение

Базы данных встречаются везде, где происходит обработка данных. На простейшем уровне базой данных можно считать любой файл, а на самом сложном - дорогую и сложную реляционную базу данных, обрабатывающую тысячи транзакций в секунду. Между этими полюсами расположены бесчисленные механизмы ускоренного доступа к более или менее структурированным данным. Perl поддерживает работу с базами данных на любом из этих уровней.
На заре компьютерной эпохи люди заметили, что базы данных на основе плоских файлов плохо подходят для работы с большими объемами информации. Плоские файлы улучшались посредством введения записей фиксированной длины или индексирования, однако обновление требовало все больших затрат, и некогда простые приложения увязали в болоте ввода/вывода. Умные программисты почесали в затылках и разработали более удачное решение. Поскольку хеш, находящийся в памяти, обеспечивает более удобный доступ к данным по сравнению с массивом, хеш на диске также упростит работу с данными по сравнению с "массивообразным" текстовым файлом. За ускорение доступа приходится расплачиваться объемом, но дисковое пространство в наши дни стоит дешево (во всяком случае, так принято считать).
Библиотека DBM предоставляет в распоряжение программистов простую и удобную базу данных. С хешами, ассоциированными с DBM-файлами, можно выполнять те же операции, что и с хешами в памяти. В сущности, именно так построена вся работа с базами данных DBM в Perl. Вы вызываете dbmopen с именем хеша и именем файла, содержащего базу данных. Затем при любом обращении к хешу Perl выполняет чтение или запись в базе данных DBM на диске.
Рецепт 14.1 демонстрирует процесс создания базы данных DBM, а также содержит рекомендации относительно ее эффективного использования. Хотя с файла- 1 ми DBM допускаются все операции, разрешенные для простых хешей, возникают проблемы быстродействия, неактуальные для хешей в памяти. Рецепты 14.2 и 14.4 разъясняют суть этих проблем и показывают, как справиться с ними. С файлами DBM также можно выполнять операции, недоступные для обычных хешей. Два примера таких операций рассматриваются в рецептах 14.6 и 14.7.
Разные реализации DBM обладают разными возможностями. Старая функция dbmopen позволяла использовать лишь ту библиотеку DBM, с которой был построен Perl. Если вы хотели использовать dbmopen для чтения базы данных одного типа и записи в другой тип - считайте, что вам не повезло. Положение было исправлено в Perl версии 5, где появилась возможность связать хеш с произвольным классом объекта - см. главу 13 "Классы, объекты и связи". В следующей таблице перечислены некоторые доступные библиотеки DBM.

Особенности

NDBM

SDBM

GDBM

DB

Программное обеспечение для связи поставляется с Perl

Да

Да

Да

Да

Исходные тексты поставляются с Perl

Нет

Да

Нет

Нет

Возможность распространения

Нет

Да

GPL'

Да

исходных текстов

 

 

 

 

 

 

 

 

Доступность через FTP

Нет

Да

Да

Да

Легкость построения

-

Да

Да

Нормально

Частое применение в UNIX

Да3

Нет

Нет4

Нет4

Нормальное построение в UNIX

-

Да

Да

Да5

Нормальное построение в Windows

-

Да

Да

Да6

Размер кода

7

Малый

Большой

о

Большой

Использование диска

9

Малое

Большое

Нормально'

Скорость

9

Низкая

Нормальная

Высокая

Ограничение размера блока

4Кб

1Кб10

Нет

Нет

Произвольный порядок байтов

Нет

Нет

Нет

Да

Порядок сортировки, определяемый

Нет

Нет

Нет

Да

пользователем

 

 

 

 

 

 

 

 

Поиск по неполному ключу

Нет

Нет

Нет

Да

 

 


1 Применение кода с общей лицензией GPL в программах должно удовлетворять некоторым условиям. За дополнительной информацией обращайтесь на www.gnu.org.
2 См. библиотечный метод DB_File. Требует символических ссылок.
3 На некоторых компьютерах может входить в библиотеку совместимости с BSD.
4 Кроме бесплатных версий UNIX - Linux, FreeBSD, OpenBSD и NetBSD.
5 При наличии ANSI-компилятора С.
6 До выхода единой версии 5.005 существовало несколько разных версий Perl для Windows-систем, включая стандартный порт, построенный по обычной поставке Perl, и ряд специализированных портов. DB, как и большинство модулей CPAN, строится только в стандартной версии.
7 Зависит от поставщика.
8 Уменьшается при компиляции для одного метода доступа.
9 Зависит от поставщика.
10 По умолчанию, но может переопределяться (с потерей совместимости для старых файлов).
NDBM присутствует в большинстве систем семейства BSD. GDBM представляет собой GNU-реализацию DBM. SDBM входит в поставку XII и в стандартную поставку Perl. DB означает библиотеку Berkeley DB. Хотя остальные библиотеки фактически реализуют заново исходную библиотеку DB, код Berkeley DB позволяет работать с тремя разными типами баз данных и старается устранить многие недостатки, присущие другим реализациям (затраты дискового пространства, скорость и размер).
Строка "Размер кода" относится к размеру откомпилированной библиотеки, а строка "Использование диска" - к размеру создаваемых ей файлов баз данных. Размер блока определяет максимальный размер ключа или значения в базе. Строка "Произвольный порядок байтов" говорит о том, использует ли система баз данных аппаратный порядок следования байтов или создает переносимые файлы. Сортировка в пользовательском порядке позволяет сообщить библиотеке, в каком порядке должны возвращаться списки ключей, а поиск по неполному ключу позволяет выполнять приблизительный поиск в базе.
Большинство программистов Perl предпочитает берклиевские реализации. На многих системах эта библиотека уже установлена, и Perl может ей пользоваться. Другим мы рекомендуем найти эту библиотеку в CPAN и установить ее. Это заметно упростит вашу жизнь.
DBM-файлы содержат пары "ключ/значение". В терминологии реляционных баз данных вы получаете базу данных, которая содержит всего одну таблицу с двумя полями. В Рецепте 14.8 показано, как использовать модуль MLDBM с CPAN для хранения сложных структур данных в DBM-файлах.
При всех своих достоинствах модуль MLDBM не может преодолеть главное ограничение: критерием для извлечения записи является содержимое лишь одного столбца, ключа хеша. Если вам понадобится сложный запрос, могут возникнуть непреодолимые трудности. В таких случаях подумайте о специализированной системе управления базами данных (СУБД). Проект DBI содержит модули для работы с Oracle, Sybase, mSQL, MySQL, Ingres и другими системами. По адресам http://www.hermetica.com/technologia/perl/DBI/index.html и http:// www.perl/com/CPAN/modules/by-category/07_Database_Interfaces/B настоящее вре-мя имеются следующие модули:
AcsiiDB   DBIDb   MLDBM   OLE   Pg   Sybase
CDB_File   DBZ_File   Fame   Msql   ObjStore    Postgres
DBD   DB_File   Ingperl   MySQL   Oraperl   Sprite XBase

14.1. Создание и использование DBM-файла

Проблема

Вы хотите создать, заполнить, просмотреть или удалить значения из базы л.ж ных DBM.

Решение

Воспользуйтесь функцией dbmopen или tie, чтобы открыть базу и сделать ее доступной через хэш. Затем работайте с хэшем, как обычно. После завершения работы вызовите dbmclose или untie.
dbmopen
use DB_File: # необязательно; переопределяет
# стандартный вариант
dbmopen %HASH, FILENAME, 0666 # открыть базу данных через %НАSН
or die "Can't open FILENAME: $!\n";
$V = $HASH{KEY}; # Получить данные из базы
$HASH{KEY} = VALUE; # Занести данные в базу
if (exists $HASH{KEY}) { # Проверить наличие данных в базе
# . . .
}
delete $HASH{KEY};
dbmclose %HASH;
tie
use DB File;
# Удалить данные из базы
# Закрыть базу данных
# Загрузить модуль баз данных
tie %HASH, "DB_File", FILENAME # Открыть базу данных
or die "Can't open FILENAME: $!\n"; # через %HASH
$V = $HASH{KEY}; # Получить данные из базы
$HASH{KEY} =o VALUE; # Занести данные в базу
if (exists $HASH{KEY}) { # Проверить наличие данных в базе # . . . } delete $HASH{KEY}; # Удалить данные из базы untie %hash; #
Закрыть базу данных

Комментарий

Работа с базой данных через хэш отличается широкими возможностями и простотой. В вашем распоряжении оказывается хэш, состояние которого сохраняется и после завершения программы. Кроме того, он работает намного быстрее, чем хэш, полностью загружаемый при каждом запуске; даже если хэш состоит из миллиона элементов, ваша программа запустится практически мгновенно.
Программа из примера 14.1 работает с базой данных так, словно она является обычным хэшем. Для нее даже можно вызывать keys или each. Кроме того, для связанных DBM-хэшей реализованы функции exists и defined. В отличие от обычного хэша, для DBM-хеша эти функции идентичны.
Пример 14.1. userstats
#!/usr/bin/perl -w
# userstats - вывод статистики о зарегистрированных пользователях.
# При вызове с аргументом выводит данные по конкретным пользователям.
use DB_File;
$db = '/tmp/userstats.db'; # База для хранения данных между запусками
tie(%db, 'DB_File', $db)
or die "Can't open DB_File $db : $!\n":
if (@ARGV) {
if ("@ARGV" eq "ALL") {
@ARGV = sort keys %db;
} foreach $user (@ARGV) {
print "$user\t$db{$user}\n";
} } else {
@who = 'who'; # Запустить who(1)
if ($?) {
die "Couldn't run who: $?\n"; # Аварийное завершение
}
# Извлечь имя пользователя (первое в строке) и обновить
foreach $line (@who) {
$line =- /"(\S+)/;
die "Bad line from who: $line\n" unless $1,
$db{$1}++;
}
}
untie %db;


Мы воспользовались командой who для получения списка зарегистрированных пользователей. Обычно результат выглядит следующим образом:
gnat ttyp1 May 29 15:39 (coprolith.frii.com)

Если вызвать программу userstats без аргументов, она проверяет зарегистрированных пользователей и соответствующим образом обновляет базу данных. Передаваемые аргументы интерпретируются как имена пользователей, о которых следует вывести информацию. Специальный аргумент "ALL" заносит в @ARGV отсортированный список ключей DBM. Для больших хэшей с множеством ключей это обойдется слишком дорого - лучше связать хэш с В-деревом (см. рецепт 14.6).
> Смотри также --------------------------------
Документация по стандартным модулям GDBM_File, NDBM_File, SDBM_ File, DB_File;perlrie(1); рецепт 13.15. Влияние umask на процесс создания файлов рассматривается в рецепте 7,1.


copyright 2000 Soft group