Индексы в наборе данных
Важнейшей проблемой для любой БД является достижение максимальной производительности и ее сохранение при дальнейшем увеличении объемов хранимых данных. Использование индексов позволяет решить эту задачу. Индекс представляет собой часть базы данных, в которой содержится информация об организации данных в таблицах БД.
В отличие от ключей, которые просто идентифицируют отдельные записи, индексы занимают дополнительные объемы памяти (довольно значительные) и могут храниться как совместно с таблицами, так и в виде отдельных файлов.
Индексы создаются вместе со своей таблицей и обновляются при модификации данных. При этом работа по обновлению индекса для большой таблицы может отнимать много ресурсов, поэтому имеет смысл ограничить число индексов для таких таблиц, где происходит частое обновление данных.
Индекс содержит в себе уникальные идентификаторы записей и дополнительную информацию об организации данных. Поэтому если при выполнении запроса сервер или локальная СУБД обращается для отбора записи к индексу, то это занимает значительно меньше времени, так как идентификатор, очевидно, гораздо меньше самой записи. Кроме этого, индекс "знает", как организованы данные, и может ускорять обработку за счет группирования записей по сходным значениям параметров.
Создание для БД эффективного набора индексов является нетривиальной задачей. Во-первых, нужно верно определить оптимальное число индексов для каждой таблицы. Во-вторых, каждый индекс должен содержать только необходимые поля, при этом большую роль играет их упорядочение.
В подавляющем большинстве СУБД при создании индексов требуется только задать поля и название индекса, вся остальная работа выполняется автоматически.
Естественно, что в компонентах доступа данных VCL Delphi используются все возможности такого мощного инструмента, как индексы. Причем, свойства и методы для работы с индексами присутствуют только в классе TTable, так как в компоненте TQuery работа с индексами осуществляется средствами SQL. В ближайшем общем предке — классе TBDEDataSet — возможности для использования индексов отсутствуют.
Набор данных на основе компонента TTable может работать и без применения индексов, но для этого соответствующая таблица БД не должна иметь первичного ключа — случай довольно редкий. Поэтому по умолчанию в наборе данных используется первичный индекс. При открытии набора данных все записи отсортированы в соответствии с первичным ключом, но только в том случае, если свойство Defaultindex имеет значение True.
Для того чтобы подключить к набору данных вторичный индекс, необходимо присвоить свойству indexName название индекса. Если свойство не имеет значения, то в наборе данных используется первичный индекс. Это свойство используется при задании индексов для таблиц Paradox и dBASE.
Альтернативный способ задания индекса заключается в использовании свойства indexFieldNames, в котором задается перечень имен полей необходимого индекса, разделенных точкой с запятой. В Инспекторе объектов для этого свойства список полей для существующих индексов создается автоматически, разработчику остается только сделать выбор. Такое автоматическое создание используется при задании индексов для таблиц серверов SQL.
Список имен всех индексов можно получить при помощи метода GetIndexNames.
Изменение текущего индекса можно осуществлять без отключения набора данных, поэтому в приложениях очень удобно делать сортировку данных по индексам. Такой метод смены индексов называется индексацией "на лету".
После установки индекса количество полей в индексе передается в свойство
IndexFieldCount.
Информация об индексах набора данных содержится в свойстве indexDefs. В нем для каждого индекса создается структура TindexDef, ее свойства представлены в табл. 16.5. Свойство indexDefs представляет собой экземпляр класса TindexDefs (табл. 16.6), в котором доступ к информации об индексах осуществляется через свойство items, являющееся списком объектов TindexDef.
Параметры описания индекса определяются свойством Options, имеющим тип TIndexOptions. Для индекса возможны сочетания следующих параметров:
-
ixprimary- первичный индекс;
-
ixunique — значения индекса уникальны;
-
ixDescending — индекс ранжирует записи в обратном порядке;
-
ixCaseinsensitive — индекс ранжирует записи без учета регистра символов;
-
ixExpression — в индексе используется выражение (для индексов dBASE);
-
ixNonMaintained — индекс не обновляется при открытии таблицы.
Свойство GroupingLevel позволяет ограничить область применения индекса. Если значение этого свойства равно нулю, индекс упорядочивает все записи набора данных. В противном случае действие индекса распространяется на группы записей, имеюших одинаковые значения для того числа полей, которое задано свойством.
Описания индексов, наряду с описаниями полей (гл. 17), также используются при создании новых таблиц БД. Для каждого планируемого индекса перед вызовом метода createTable необходимо создать или скопировать из существующего набора данных соответствующее описание. Тогда при создании таблицы индексы будут добавлены автоматически:
with Tablel do
begin
DatabaseName := 'DBDEMOS';
TableType := ttParadox;
TableName := 'DemoTable';
{Создание описаний полей}
with IndexDefs do begin Clear;
AddIndexDef;
with Items [0] do begin Name : = ";
Fields := 'Fieldl';
Options := [ixPrimary, ixUnique];
end;
CreateTable;
end;
При создании описаний индексов использован метод AddIndexDef, который при каждом вызове добавляет к списку items объекта TindexDefs новый объект TindexDef. Таким образом, сначала создается первичный индекс (в таблицах Paradox он не имеет имени), затем вторичный индекс secondIndex. Для каждого описания обязательно определяются составляющие индекс поля и параметры индекса (свойства Fields и options).
