Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Тема_2_3_FoxИндексирование.doc
Скачиваний:
4
Добавлен:
11.08.2019
Размер:
81.92 Кб
Скачать

Тема 2.3. Индексирование: понятие индекса, типы индексных файлов. Создание, активация и удаление индекса.

  1. Индексирование баз данных

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

Если файл проиндексирован, команды DISPLAY, EDIT, BROWSE, SKIP, REPLACE и все другие команды, связанные с движением в базе данных, перемещают указатель записей в соответствии с индексом, а не с физическим порядком расположения записей. Так, команды GO TOP и GO BOTTOM устанавливают указатель записей не на первую (номер 1) и последнюю физические записи, а на начальную и конечную записи индекса соответственно.

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

Аппарат индексирования является важнейшим инструментом любой реляционной СУБД. И хотя практически все действия над данными могут быть осуществлены и без участия индексов, совершенно немыслимо их игнорирование при создании реальных информационных систем. Только использование индексов позволяет достичь приемлемых скоростных характеристик обработки данных, поскольку поисковые операции (присутствующие прямо или косвенно) используются в программах очень широко. Однако за все надо платить. Сами индексные файлы занимают некоторое место на диске. Размер индексного файла сравним с объемом дискового пространства, занимаемого полем базы данных, по которому было произведено индексирование. Таким образом, например, если база проиндексирована по всем полям, суммарный размер всех 'индексов будет близок (или больше) к размеру всей базы данных. Кроме того, замедляются операции ввода/редактирования данных в базе, поскольку при дополнении ее новой записью индексный файл должен быть автоматически перестроен в соответствии с новыми или измененными данными.

В FoxPro можно создать два типа индексных файлов:

• Обычный индексный файл. Он имеет расширение имени IDX и содержит один индексный ключ. Его можно также назвать одноиндексным файлом.

• Мультииндексный файл с расширением имени CDX. Такой файл может хранить сразу несколько индексных выражений и является по существу соединением нескольких простых индексных файлов. Каждый отдельный индекс в нем будем называть ввиду отсутствия подходящего термина словом "тег", взятым непосредственно из технической документации (TAG - этикетка). Каждый тег имеет свое имя. Мультииндексные файлы могут быть двух видов: структурный мультииндексный файл с именем, совпадающим с именем базы данных, и обычный мультииндексный файл с произвольным именем.

Структурный файл всегда автоматически открывается вместе со своей базой. Его нельзя закрыть, хотя можно сделать неглавным.

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

INDEX ON <выр> ТО <IDХ-файл>/ТАG <имя тега> [OFDХ-файл>] [FOR <условие>] [COMPACT] [DESCENDING] [UNIQUE] [ADDITIVE]

В FoxPro используется компактная, более быстрая в обработке структура индексного файла. Мультииндексный файл всегда компактный. Обычный (IDX) индексный файл строится обычным образом, если не указан параметр COMPACT. Сделано это для совместимости со старыми индексными файлами из СУБД FoxBASE и FoxPro-l.x. Все новые индексные файлы, конечно, следует создавать компактными. Опции команды:

<выр> - индексный ключ-выражение. Его длина может достигать 100 символов для IDX-файлов и 240 для CDX-файлов. Чаще всего ключ это имя поля, по которому нужно упорядочить файл. Однако, ключ может быть и составным - из нескольких полей. Он может быть и функцией полей и переменных.

ТО <IDХ-файл> - дает имя одноиндексному файлу.

TAG <имя тега> [OF <CDX-файл>] - задает имя тега в мультииндексном файле. Если в команде присутствует фраза OF <CDX-файл>, то мультииндексный файл получит указанное имя. Если нет, то будет создан структурный мультииндексный файл с именем, совпадающим с именем базы данных. Команда может использоваться как для создания нового мультииндексного файла, так и для дополнения уже существующего CDX-файла новым тегом.

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

COMPACT - с этой опцией будет создан компактный IDX-файл. Целесообразно использовать только компактные индексы. Возможность создавать обычные индексы оставлена лишь для совместимости с предыдущими версиями пакета. DESCENDING - индексирование будет выполнено по убыванию. Этот режим можно указывать только доя мультииндексных CDX-файлов. Для IDX-файлов индексирование всегда осуществляется по возрастанию, однако параметр DESCENDING можно включить в команды открытия индексов любого типа, независимо от того, какой закон был указан в команде индексирования. По умолчанию индексирование выполняется по возрастанию.

UNIQUE - означает, что, если в базе данных встречаются записи с одинаковым значением ключа, все такие записи, кроме первой, игнорируются (не включаются в индекс). Этим процессом можно управлять также с помощью команды SET UNIQUE TO. ADDITIVE - вновь создаваемые индексные файлы не закроют уже открытые к этому моменту. По умолчанию вновь создаваемые индексы закрывают все ранее открытые индексы для текущей базы данных.

Положим, открыта база KADR.DBF. Ниже приведены три команды создания индексных файлов по полю FAM. В первом случае создается компактный одноиндексный файл KADR_FAM.IDX, во втором – мультииндексный файл KADR.CDX с тегом FAM, в третьем структурный мультииндексный файл KADR.CDX с тегом FAM.

INDEX ON Sam TO kadrfam.idx COMPACT

INDEX ON fam TAG fam OF _kadr.cdx

INDEX ON fam TAG fam

Расширение имен индексных файлов можно не указывать. Здесь они приведены только для наглядности. Рассмотрим несколько примеров индексирования. Пример. Пусть мы хотим упорядочить базу KADR в порядке возрастания табельных номеров. Тогда необходимо создать индексный файл по полю TAB. Назовем его KADRTAB.IDX.

USE kadr

INDEX ON tab TO kadrtab

LIST tab, fam

Record # TAB FAM

3 6 КУЛАКОВА М.И.

1 13 СИДОРОВ П.С.

7 54 ЯКОВЛЕВ А. И.

2 98 ПОТАПОВ Д.П.

4 234 ПОПОВ А.А.

6 468 МИРОНОВ Р.И.

5 890 РОМАНОВА М.С.

Как видно, команда LIST показала записи именно в желаемом, а не в фактическом порядке. Файл базы KADR.DBF никакому изменению не подвергся, но всеми перемещениями указателя записей управляет теперь индексный файл K.ADRTAB.IDX.

Каково содержимое индексного файла? Хотя в FoxPro не предусмотрена какая-либо возможность непосредственного доступа к индексу, мы можем просмотреть его во внутреннем текстовом редакторе FoxPro (с помощью команды MODIFY FILE KADTRAB.IDX). Тогда мы увидим, что кроме технической информации в заголовке файл KADRTAB.IDX будет содержать значения ключевого поля TAB индексируемой базы данных, расположенные в порядке возрастания, и (в закодированной форме) фактические номера этих записей в базе данных. В нашем случае 3-6, 1-13, 7-54, 2-98, 4-234 и т.д.

Пример. Рассмотрим включение FOR-условия в команду индексирования. Пусть требуется создать индексный файл KADRPOL.IDX, содержащий ссылки только на те записи базы KADR.DBF, которые соответствуют всем мужчинам (ро1='М'), причем упорядоченные в алфавитном порядке фамилий.

USE kadr

INDEX ON fam TO kadrpol FOR pol='M' COMPACT

LIST FAM, POL

Record # FAM POL

6 МИРОНОВ Р.И. М

4 ПОПОВ А.А. М

2 ПОТАПОВ Д.П. М

1 СИДОРОВ П.С. М

7 ЯКОВЛЕВ А.И. М

Видим, что содержание и порядок предъявления записей из базы KADR.DBF отвечают желаемым.

Если порядок предъявления фамилий безразличен и. по ним не предполагается поиск, ключевое поле (в данном случае FAM) можно опустить, заменив его пробелом в команде индексирования

INDEX ON ' 'TO kadrpol FOR pol='M' COMPACT

При этом индексный файл будет меньших размеров.

Если индексный файл был уже создан, его нужно открыть при внесении новых записей или редактировании старых (если затрагиваются индексные поля) и, конечно, если предполагается индексный поиск. Индексные файлы могут быть открыты совместно с открытием своей базы данных (<DBF-файла>) командой:

USE <DBF-файл> [IN <область>] [ALIAS <псевдоним>] [AGAIN] [NOUPDATE]

[INDEX <список индексных файлов > [ORDER [<BыpN>/<IDX-файл>/[TAG] <имя тега> [OF <CDX-файл>] [ASCENDING/DESCENDING]]]] Опции команды:

IN <область> - если указан параметр <область>, база откроется не в текущей, а в указанной рабочей <области>, но автоматический переход в <область> при этом не произойдет. По умолчанию база открывается в текущей области. Если не осуществлен переход в какую-либо область, вначале всегда занимается область 1 (или А). Подробнее понятие рабочей области будет рассмотрено позже.

AGAIN - позволяет открыть открытый уже файл базы данных в другой рабочей области. В области, где он был открыт ранее, такой файл может быть доступен в режиме только-чтение. Однако каждый индекс может быть открыт одновременно только для одной из областей.

INDEX <список индексных файлов> - указывает перечень открываемых индексных файлов. Здесь важен порядок перечисления индексов. Первый в списке индекс считается главным, если не использована опция ORDER. Понятие главного индекса будет введено ниже.

ALIAS <псевдоним> - устанавливает для базы кроме собственного еще любое другое имя. Если разным базам дать одинаковый псевдоним, далее они могут под этим именем обрабатываться в одной и той же программе. NOAPDATE - указывает на то, что база будет открыта только для

просмотра (редактирование запрещено).

Открытие файла всегда устанавливает указатель записей на его первую запись.

Новая команда USE открывает новый файл базы данных одновременно с закрытием старого в текущей области. Команда USE без имени файла закрывает соответствующий файл базы данных и все сопровождающие его вспомогательные файлы (типа IDX и др.) в текущей или другой (если она указана) области.

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

• SET INDEX TO [<список индексных файлов> ORDER <BыpN>/<IDX-файл>/[TAG] <имя тега> [OF <СDХ-файл>] [ASCENDING/DESCENDING]] [ADDITIVE]

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

ORDER <BыpN> - опция указывает номер главного индексного файла среди перечисленных в <списке> открываемых IDX-файлов или среди тегов CDX-файла (номер по порядку создания), если нас не устраивает назначение главного индекса по умолчанию. Указание опции ORDER без аргумента или задание параметра <BыpN>=0 означает, что, хотя индексы откроются, главный индекс не будет назначен. ORDER <IDX-файл> - главный индекс задается указанием имени индексного файла. . ORDER [TAG] <имя тега> OF <CDX-файл> - главный индекс задается именем тега.

ASCENDING/DESCENDING - определяет порядок использования индекса (по возрастанию/убыванию), даже если при его создании был использован противоположный закон. ADDITIVE - открытие новых индексов не закрывает старые.

Команда SET INDEX TO без параметра закрывает все индексные файлы, кроме структурного, для текущей базы. Такое же действие осуществляет команда

• CLOSE INDEX

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

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

Применение компактного индекса дает преимущества в скорости (по сравнению с обычным индексом), в особенности когда обрабатывается сразу несколько баз и индексов, и тем заметнее, чем больше их размер.

Индексный ключ в команде создания индексного файла может быть составным, включая имена нескольких полей, соединенных знаком "+". Однако поля должны иметь один и тот же тип или должны быть приведены к одному и тому же (обычно символьному) типу функциями преобразования типов. При этом нужно очень внимательно следить за видом окончательного индексного выражения, полученного после преобразования и сцепления данных из разных полей. Ведь именно оно запоминается в индексном файле и по нему ведутся поиск и упорядочение записей. Это относится и к заданию ключа поиска в команде SEEK, который по типу и виду должен отвечать именно индексному выражению, а не исходному значению индексируемого поля/полей базы. Хотя предельно разрешенная длина индексного выражения в FoxPro - ^100 символов (для CDX-файлов 240 символов), следует по возможности ограничивать его размер. Это сокращает время доступа к данным и величину индексного файла. Например, при сортировке записей по алфавиту часто бывает достаточно упорядочение их на глубину всего в три-четыре символа. Здесь (а также если индексируемое поле длиннее разрешенных 100/240 символов) при указании индекса можно воспользоваться функцией выделения в поле нужного количества знаков слева – LEFT(). Однако следует учитывать, что сокращение длины индексного ключа относительно длины поля означает, что данные, которые имеют различия, оставшиеся за пределами ключа, будут считаться в индексе одинаковыми.

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

Пример. Пусть требуется упорядочить базу KADR.DBF по полу, а внутри - по фамилии, т.е. по полям POL и FAM. Назовем этот индексный файл именем POLFAM.IDX.

USE kadr

INDEX ON pol+fam TO polfam COMPACT

LIST pol,fam

Record # POL FAM

3 Ж КУЛАКОВА М.И.

5 Ж РОМАНОВА М.С.

6 М МИРОНОВ Р.И. 4 М ПОПОВ А.А. 2 М ПОТАПОВ.Д.П. 1 М СИДОРОВ П.С. 7 М ЯКОВЛЕВ А.И.

Видим, что команда LIST выдает записи в желаемом порядке. Сначала идут все фамилии женщин (буква Ж идет раньше буквы М), а затем все фамилии мужчин, расположенные в алфавитном порядке.

Команда индексного поиска SEEK является аналогом команды LOCATE для последовательного поиска. Однако команде продолжения поиска CONTINUE нет индексного аналога. Причина здесь очевидна. После того как командой SEEK найдена первая нужная запись, розыск остальных записей, удовлетворяющих ключу поиска, является тривиальным. Следующая такая запись (если есть) находится в индексе непосредственно ниже найденной, и переход на нее может быть выполнен просто командой SKIP. Единственно следует предусмотреть, чтобы в отобранное множество не попали записи, идущие сразу под нужными.

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

Если индексный файл был ранее создан, но вы забыли его своевременно открыть и внесли какие-то изменения в базе, то необходимо его открыть и обновить командой

REINDEX

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

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

Если вам предстоит создание сложного индекса и вы не уверены, что правильно задали индексный ключ в команде индексирования, следует проверить вид самого индекса. Для этого можно прибегнуть к просмотру IDX-файла непосредственно в текстовом редакторе FoxPro. Однако осмысленный анализ "на глаз" возможен только для простых IDX-файлов, где индексные ключи находятся практически в естественной форме. Для компактных и тем более для CDX-файлов такой анализ ввиду их сложности практически невозможен. Удобнее всего вывести индексное выражение в команде BROWSE в качестве вычисляемого поля. Кроме того, полезно также вывести и номер каждой записи. Для предъявления индексного выражения можно прямо включить в команду BROWSE индексный ключ из команды INDEX после слова ON, но гораздо проще воспользоваться функцией

• KEY(<BыpN>) где <BыpN> - номер индекса в команде открытия.

Полученное символьное выражение "наполняется" конкретным значением с помощью функции подстановки EVALUATE().