HTML page
Базы данных
Введение
Базы данных встречаются везде, где происходит обработка данных. На простейшем уровне базой данных можно считать любой файл, а на самом сложном - дорогую и сложную реляционную базу данных, обрабатывающую тысячи транзакций в секунду. Между этими полюсами расположены бесчисленные механизмы ускоренного доступа к более или менее структурированным данным. 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.