Традиционно такие приложения делятся на локальные приложения и приложения в архитектуре клиент/сервер, которые в свою очередь подразделяются на клиентические и серверные составляющие Локальными называются программы, расположенные на одном компьютере с базой данных. При этом база данных управляется сравнительно маломощной СУБД, а язык SQL не является определяющим при создании запросов и обмене данными. Иногда база данных может располагаться на фиксированном сетевом диске в локальной сети.
Программа называется соответствующей архитектуре клиент/сервер, если она имеет мощный сервер БД, отвечающий за обработку поступающих запросов и передачу результата клиентам. В качестве СУБД используются мощные промышленные серверы, для создания запросов и управления данными используется SQL. Также обязательной составляющей частью должны быть клиентические приложения, обеспечивающий отображение данных и интерфейс с конечным пользователем. Клиентическое ПО чаще всего располагается на удаленных рабочих местах, в сетях, требующих отдельного администрирования.
По мере развития локальных и глобальных компьютерных коммуникаций, распространение персональных компьютеров такая классификация стала утрачивать актуальность.
Одновременно с усложнением решаемых задач усложнялись и совершенствовались программы для работы с БД. Появились деления на однопользовательские и многопользовательские локальные СУБД, соответственно локальные программы стали делиться на однопользовательские и сетевые. Возникла дополнительная классификация клиентических приложений на "слабые" ("тонкие") и "сильные" ("толстые") , появились разнообразные способы связи между клиентом и сервером, алгоритмы обслуживания очередей клиентов и способы управления транзакциями.
Согласно новой классификации все приложения для работы с базами данных делятся на группы в зависимости от числа уровней обработки данных.
Те программы которые раньше назывались локальными (независимо от способа связи с СУБД) , чаще всего сейчас входят в число одноуровневых приложений, так как обработка данных в них ведется в единственном месте. Клиент/серверные приложения стали делиться на двухуровневые (классический клиент/сервер) и трехуровневые (клиент/сервер с ПО промежуточного слоя) .
С точки зрения Delphi при учете уровней обработки данных из рассмотрения выпал процессор БД и ВДЕ, который берет на себя большую часть низкоуровневой обработки данных и установку соединения между СУБД и приложением. НО эта классификация подразумевает разделения на уровни только создаваемой разработчиком логики обработки данных, без учета стандартных используемых механизмов. Поэтому в документации по Delphi двухуровневые программы (с учетом уровня обработки ВДЕ) часто называются одноуровневыми приложениями, основными на ВДЕ.
Терминология
Реляционная база данных - база данных, в которой все данные представлены в виде прямоугольных таблиц, а все операции над базой данных сводятся к манипуляциям со строками и столбцами таблиц. При разработке приложений для работы с базами данных наиболее часто решаемая разработчиками программа-это получение по некоторому запросу из базы данных и отображение на экране определенного множества значений. Иногда это множество полностью соответствует содержимому какой-либо таблицы, но чаще это часть таблицы или объединение записей нескольких таблиц, переданное в приложение в результате выполнения запроса, будем называть набором данных.
Объединение - это логическое отношение между двумя таблицами на основе внешнего ключа.
Первичный ключ - поле или группа полей, обеспечивающих уникальность каждой записи в таблице.
Внешний ключ-поле или группа полей, которые не совпадают с первичным ключом, и используется для объединения с другими таблицами.
Словарь данных - специализированная база данных, используемая в приложениях Delphi для хранения наборов атрибутов. Также в него могут входить и структуры баз данных целиком. Словарь данных не может хранить данные об объектах окружающего мира.
Набор атрибутов - структура, которая содержит информацию о свойствах поля (его типе, размере и т.д.) , а также об особенностях визуализации данного поля.
В приложениях Delphi набор может быть получен не только в результате выполнения запроса SQL, но и простым открытием таблицы компонентом T Table (с фильтром или без него) . Следует отметить что любое обращение к БД ВДЕ, которые трансформируют любые виды требований на наборы данных в собственные запросы.
Процессор баз данных Borland Database Engine (ВДЕ) 1. Архитектура ВДЕ является важнейшей составляющей частью механизма доступа к данным реализованного в Delphi.
Архитектура ВДЕ основана на драйверах которые обеспечивают обмен данными с конкретными СУБД. Ядро процессора БД составляет совокупность динамических библиотек, содержащих механизмы обмена данными, управления запросами, поддержки национальных языков и т.д. Назначение всех динамических библиотек представлено в таблице1.
В состав ВДЕ включены стандартные драйверы, обеспечивающие доступ к СУБД Paradox, dBase, Foxpro и текстовым файлом. Помимо этого в ВДЕ имеется простой механизм подключения любых драйверов ОДБС (например, Microsoft Access) т создание на их основе пакетов ОДВС.
Доступ к данным серверов SQL обеспечивает отдельная система драйверов-SQL Links. С их помощью в Delphi можно разрабатывать приложения для серверов Dracle 8, Sybase, ДВ2 и, естественно, Interbase.
Эта особенность архитектуры ВДЕ обеспечивает ряд существенных преимуществ.
1. Реальное разделение программного кода и механизм доступа к данным. Причем сам доступ также осуществляется на нескольких уровнях -ВДЕ, драйвера, сервера БД. Приложение Delphi для работы с БД можно настроить на использования с любой СУБД, для которой имеется соответствующий драйвер, буквально за несколько минут. При этом перекомпиляция самой программы не требуется. Плата за такую великолепную переносимость - скорость обмена данными через ВДЕ и драйверы несколько меньше чем напрямую между приложением и СУБД.
2. Разделение драйверов и выделение в специальную группу драйверов для серверов SQL позволило гораздо полнее использовать функциональные возможности серверов БД, а применение единого API сняло остроту проблемы интерпретации процесса выполнения транзакций разными серверами.
3. ВДЕ идеально подходит для создания приложений для архитектуры клиент/сервер, так как обеспечивает следующие функции: - обработка запросов в диалоговом режиме; - представление через ВДЕ вызовов операционной системы; - модифицируемые запросы; - поддержка хранимых процедур; - управление регистрацией пользователя.
Таблица 1. Ядро процессора баз данных ВДЕ 5 Имя файла Назначение DBClient. dll Динамическая библиотека, отвечающая за работу клиентской части приложения IDPROV. dll Динамическая библиотека, отвечающая за работу серверной части приложения IDAPI32. dll Базовая динамическая библиотека ВДЕ BLW32. dll Динамическая библиотека, обеспечивающая поддержку драйверов национальных языков IDBAT32. dll Дин. б-ка, с функциями межтабличного переноса данных IDQBE32. dll Дин. б-ка, обеспечивающая работу запросов по примеру (Query By Example) IDSQL32. dll Дин. б-ка, обеспечивающая обработку запросов SQL IDASCI32. dll Дин. б-ка, обеспечивающая работу драйвера текстовых файлов IDPDX32. dll Дин. б-ка, обеспечивающая работу драйверов Paradox IDDBAS32. dll Дин. б-ка, обеспечивающая работу драйвера dBase DODBS32. dll Дин. б-ка, обеспечивающая работу драйвера сокета ODBC IDR20009. dll Дин. б-ка, ресурсов, содержащая сообщения об ошибках IDDAO32. dll Дин. б-ка, обеспечивающая работу драйвера Microsoft Access 95 и Tet Engine 3.0
IDDA3532. dll Дин. б-ка, обеспечивающая работу драйвера Microsoft Access 97 и Tet Engine 3.5
IDDR32. dll Дин. б-ка, для работы с репазиторием данных 2. Функционально ВДЕ содержит следующие составные части -Администратор системных ресурсов Управляет процессом подключения к данным- при необходимости устанавливает нужные драйверы, а по завершению работы автоматически освобождает занятые ресурсы. По этому ВДЕ использует ровно столько ресурсов, сколько необходимо.
-Система обработки запросов Обеспечивает выполнение запросов SQL и QBE от приложения к любым базам данных, для которых установлен драйвер, даже если сама СУБД не поддерживает прямое использование запросов SQL -Система сортировки Является запатентованной технологией и обеспечивает очень быстрый поиск по запросам SQL и через стандартные драйверы для Paradox и dBase.
-Система пакетной обработки Представляет собой механизм преобразования данных из одного формата в другой при выполнении операций над целыми таблицами. Эта система использована в качестве основы для компонента TBatchMove и утилиты Data Pump, входящие в стандартную постановку ВДЕ.
-Диспетчер памяти Непосредственно взаимодействует с ОС и обеспечивает эффективное использование выделяемой памяти. Ускоряет работу драйверов, которые для получения небольших фрагментов памяти обращаются к нему, а не к ОС.
-Диспетчер буфета. Управляет единой для всех драйверов буфетной областью памяти, которую одновременно могут использовать несколько драйверов. Это позволяет существенно экономить системные ресурсы.
-Транслятор данных. Обеспечивает преобразования форматов данных для различных типов БД.
-КЭШ BLOB. Используется для ускорения работы с данными в формате BLOB -SQL -генератор Транслирует запросы QBE в запросы SQL.
-Система реструктиризации. Обеспечивает преобразования наборов данных в таблицы Paradox или dBase -Система поддержки драйверов SQL Повышает эффективность механизма поиска при выполнении запроса SQL -Таблица в памяти Этот механизм позволяет создавать таблицы непосредственно в оперативной памяти. Используются для ускорения обработки больших массивов данных, сортировки, преобразования форматов данных.
-Связанные курсоры. Механизм связанных курсоров обеспечивает низкоуровневое выполнение межтабличных соединений. Для реализации подобных связей на уровне VSL достаточно установить значение нескольких свойств.
-Диспетчер конфигурации. Обеспечивает разработчику доступ к информации о конфигурации драйверов.
3. Процесс доступа к данным из BDE
Осуществляется следующим образом
1) Компонент доступа к данным приложения получает команду на открытие набора данных и при помощи унаследования от предка (T BDE Data Set) методов обращается к BDE с соответствующим запросом.
2) BDE выделяет для нового процесса необходимые ресурсы и, при необходимости, транслирует запрос в соответствии с особенностями драйвера запрашиваемой СУБД.
3) При обращении к локальной базе данных драйвер ан прямую обращается к таблицам; при обращении к серверу SQL вызывается соответствующее клиентское ПО.
4. Настройка BDE Для управления псевдонимами баз данных, настройки стандартных и дополнительных драйверов в составе BDE имеются специальная утилита-BDE Administrator.
Стандартная конфигурация BDE сохраняется в файле /DAP/. CFG. При необходимости текущую конфигурациюв в новом файле с расширением CFG.
Рабочая область утилиты BDE Administrator представляет собой двухстраничный блокнот. Страница Databases содержит иерархическое дерево, в узлах которого расположены на данный момент псевдонимы БД. При выборе какого-либо псевдонима в правой части панели появляется перечень параметров драйвера, соответствующего псевдониму, которые можно настраивать в ручную.
Страница Configuration предназначена для настройки параметров драйверов BDE, предназначенных для обеспечения доступа к СУБД и серверам БД. Также здесь определяется системная конфигурация BDE, которая включает параметры числовых форматов, дат, времени. Вся информация здесь также структуризирована в виде иерархического дерева.
При выборе в левой панели утилиты какого-либо узла, в правой части на странице Definition отображается вся необходимая информация для этого объекта. Назначение параметров локальных драйверов BDE представлено в табл. 2.
Таблица 2. Параметры драйверов BDE для локальных баз данных.
Параметр Назначение STANDART DEFOLT DRIVER Задает тип конкретного локального драйвера (Paradox, dBase, FoxPro, Asc) .
ENABLE BCD Определяет способ представления вещественных чисел. При значении True такие числа преобразуются в формат BCD (десятичные с двоичным кодированием) , который позволяет округлять погрешности высших разрядов дробной части числа. Точность составляет 20 знаков после запятой.
PATH Указывает путь к файлам базы данных.
PARADOX NET DIR Указывает путь к файлу обеспечения сетевого доступа PDOXVSRS. NET. Драйвер приложения, который работает с БД локально, должен указывать на этот файл, расположенный на том же компьютере. Драйвер приложения обращающийся к БД по сети, должен указывать на подключенный сетевой диск сэтим файлом.
VERSION Нередактируемая информация о версии драйвера.
TYPE Тип СУБД. Для Paradox имеет значение FILE только для чтения.
LANGDRIVER Определяет драйвер языковой поддержки.
BLOCK SIZE Задает размер блоков дискового пространства для хранения записей, кратно 1024.
FILL FACTOR Определяет процент заполнения блока дискового пространства при хранении индексов, по умолчанию 95%.
LEVEL Задает формат временной таблицы в памяти: 3-совместим с Paradox 3.5 и ниже 4-Paradox 4.0
5-Paradox 5.0
7-Paradox STRICTINTEGRTY Определяет возможность использования приложения на базе Paradox 4.0 более поздних таблиц с ссылочной целостностью. При значении TRUE использование разрешается, но возникает риск нарушения целостности данных.
DBASE VERSION Нередактируемая информация о версии драйвера.
TYPE Тип СУБД. Для dBASE имеет значение FILE только для чтения.
LANGDRIVER Определяет драйвер языковой поддержки.
LEVEL Задает формат таблиц. Значение соответствует номеру версии СУБД.
MDX BLOCK SIZE Размер блоков для файлов с расширением MDX, кратно 5/2 MEMO FILE BLOCK Размер блоков для файлов с данными типа memo, кратно 5/2 SIZE FOXPRO VERSION Нередактируемая информация о версии драйвера TYPE Тип СУБД. Для FoxPro имеет значение FILE только для чтения.
LANGDRIVER Определяет драйвер языковой поддержки LEVEL Имеет значение 25.
5. Интерфейс прикладного программирования.
Любое приложение Delphi, работающее с базами данных и написанное с использованием стандартных компонентов доступа к данным, обращается к данным и получает результат при помощи BDE. При этом механизм доступа к данным использует вызовы функций из API BDE.
Интерфейс прикладного программирования Delphi позволяет создать любые приложения для работы с БД с самыми разнообразными функциями. При этом не имеет значения способ доступа к данным, так как BDE обеспечивает связь приложения с базой данных на уровне драйверов и псевдонимов.
НА практике не возникает необходимости создания приложения, использующего только функции BDE без применения компонентов для доступа к данным VCL. Поэтому рассмотрим способ приложения, использующего вызовы отдельных функций BDE.
Для создания приложений на основе вызовов функций BDE необходимо выполнить следующие операции: 1. Инициализация BDE (функция DbiInit) .
2. Открытие объектов базы данных (функция Dbiopen Database) .
3. Определение рабочего каталога (функция Dbi Set Direktory) , если на предыдущем этапе не задан псевдоним БДю 4. Определение временного каталога (функция Dbi Set Private Dir) .
5. Открытие набора данных и создание курсора (функции DbiOpen Table, DbiQExec и пр. ;дескриптор курсора hDBICur) .
6. Заполнение структуры CUR Props, содержащий данные о курсоре и наборе данных (функция Dbi Get Cursor Props) .
7. Выделение памяти для буфера записи.
8. Навигация по набору данных (функции Dbi Set to Begin, Dbi Set to End, Dbi Set to Cursor ипр.)
9. Чтение необходимой записи (функции Dbi Get Relativ Recod, Dbi Get Next Recod, Dbi Get Recod, Dbi Get Prior Recod и пр.) .
10. Чтение или обновление необходимого поля (функции Dbi Get Field) .
11. Освобождение всех ресурсов (освобождение буфера записи, записи курсора, таблицы, BDE) .
При использовании в программе функции из API BDE необходимо включить в секцию uses модуль BDE.
В компонентах VCL для доступа к данным (TTable, TQuery, TStored Proc) инкапсулирован механизм взаимодействия с динамическими библиотеками BDE. Любой компонент для доступа к данным имеет в иерархии наследования класс TBDE DataSet, унаследованные методы которого используется для установления связи с базой данных через BDE. Важную роль при этом играет зарегистрированный в BDE псевдоним базы данных (свойство компонента называется DataBaseName) . Второе важнейшее свойство -Activ, имеющее тип Doolean, позволяет открыть или закрыть сеанс связи с базой данных.
Визуализацию полученных данных обычно выполняет компонент TDataSource и один или несколько компонентов отображения данных (Data Controls) . Основная задача компонента TData Scource-разделение набора данных на поля или группы полей и передача их по назначению. Он же отвечает за возврат сделанных изменений и передачу сигналов управления от пользователя в набор данных.
Любой компонент отображения данных умеет визуализировать полученные от компонента TDataSourse данные в соответствии с их типом, отслеживает правильность вносимых изменений и передает их в TDataScource.
Таким образом, компонент TDataScource служит мостом между набором данных и пользовательским интерфейсом. С точки зрения разработчика приложений процесс подключения набора данных не содержит сложностей. Эту работу выполняет механизм доступа к данным, основой которого является процессор баз данных Borland Database Engine.
Типы данных.
Универсальность Delphi подразумевают необходимость применения средств, которые бы обеспечили возможность работы с многими типами данных.
Существует большая группа типов данных, конкретная реализация которых практически не отличается от платформы к платформе. Это, например, строки, символы, целые и вещественные числа.
Есть типы данных, которые реализованы далеко не на каждой платформе. Есть, наконец, просто универсальные типы данных, но зато СУБД, на которой этот тип реализован, очень широко распространена. В Delphi применен следующий способ работы с типами данных.
Тип данных однозначно связан с конкретным полем таблицы базы данных. Свойства абстрактного поля инкапсилируют класс TField, который не имеет заранее определенных типа данных. От этого класса порождено целое семейство классов для типизированных полей, каждый из которых умеет обращаться со своим типом данных.
В классе TField имеется свойство Data Type, которое отвечает за тип данных, но оно не может быть измерено.
Практически во всех серверах БД пользователь имеет возможность создавать собственные типы данных. Для их использования в приложении Delphi имеется абстрактный тип данных и класс TADT Field. Абстрактный тип может в себя включать любой скалярный тип данных (числа, даты, ссылки, массивы, наборы данных) .
Афтоинкриментный тип данных используется для получения уникального индификатора записи. Поле автоинкриментного типа для каждой новой записи автоматически увеличивает свое значение на единицу.
Данные типа Blob (Binary Large OBject) представляют собой двоичные массивы произвольной длинны. В самом поле содержится только ссылка на отдельный файл базы данных, в котором хранится двоичный массив. Таким образом, поля типа Blob являются универсальным носителем любых данных, которые имеют сколярную и не сколярную структуру и которое можно преобразовать в двоичное представление.
Новой возможностью Delphi стало использование массивов. Этот тип организует массив из данных любой структуры, за исключением таких же массивов. Для каждого элемента массива может создаваться собственный объект TField. Для управления этим механизмом используется свойство SparseArays в классе TDataSet.
В качестве отдельного поля в набор данных можно включить и любой другой произвольный набор данных. Для этого используется специальный тип данных и класс TDataSetField. Причем каждым полем из интегрированного набора данных также можно управлять.
Ссылочный тип данных также использует внешние наборы данных, но в данном случае можно подключать и использовать только отдельные поля.
Состояние набора данных В процессе функционирования набор данных может выполнить различные операции: перемещение по записям, редактирование данных, удаление записи, и т.п. Эффективность работы и разнообразие функций обеспечивает сложный механизм доступа к данным. В нем все операции объединены в группы по функциональному признаку. Для каждой группы операций BDE выполняет ряд подготовительных действий по предварительной настройке набора данных. При этом состояние набора данных изменяется.
Итак, набор данных в любой момент времени находится в некотором состоянии, т.е. подготовлен к выполнению действий строго определенного рода. Все состояния набора данных делятся на две группы. К первой группе относятся состояние, в которое набор данных переходит автоматически, к ним относятся непродолжительные по времени состояния, сопровождающее функционирование полей набора данных (табл. 3) . Во вторую группу входят состояния, которым можно управлять из приложения, например, перевод набора данных в режим редактирования (табл. 4) .
Базовый класс TDataSet, инкапсулирующий свойства набора данных, позволяет изменять состояния, а также проверять текущее состояние набора данных. Текущее состояние набора данных передается в свойство State, имеющая вид NDataSetState.
Таблица 3. Автоматические состояния набора данных Константа состояния Описание dsNewValue Включаются при обращении к свойству NewValue поля набора данных dsOldValue Включается при обращении к свойству OldValue поля набора данных dsCurValue Включается при обращении к свойству CurValueполя набора данных dsInternalCalc Включается при расчете значений полей, для которых FindKind=frInternalCalc dsCalcFields Включается при выполнении метода onCalcFields dsBlockRead Включается механизм ускорения перемещения по набору данных dsFilter Включается при выполнении метода onFilterRecond Таблица4. Управляемые состояния набора данных Константа состояния Метод Описание dsInactive Close Набор данных закрыт dsBrowse Open Данные доступны для просмотра, но не доступны для редактирования dsEdit Edit Данные можно редактировать dsInsert Insert К наборам данных можно добавлять новые записи dsSetKey SetKey Включается механизм поиска по ключу. Также могут использоваться диапазоны Для управления состояния набора данных используются методы Open, Close, Edit, Insert. Закрытый набор данных всегда имеет не закрытое состояние dsInactiv. При открытии набора данных переход в состояние просмотра данных dsBrowse. В этом состоянии по записям набора данных можно перемещаться и просматривать их содержимое, но редактировать данные нельзя. Это основное состояние открытого набора данных, из него можно перейти в другие состояния, но любое изменение состояния происходит через просмотр данных (рис. 3) После выполнения метода Edit можно изменять значения полей для текущей записи. При перемещении на следующую запись набор данных автоматически переходит в состояние просмотра.
Метод Insert добавляет на месте текущего курсора новую пустующую запись и переводит набор данных в состояние вставки. При переходе на другую запись, после проверки на уникальность первичного ключа(если он есть) , набор данных возрастает в состояние просмотра.
Состояние установки ключа используется только в компоненте TTable при необходимости описка методами FindKey и FindNext, а также при использовании диапазонов (метод SetRang) . Это состояние сохраняется до момента вызова одного из методов поиска по ключу или метода обмена диапазона.
Состояние просмотра по блокам используется набором данных при реализации быстрого перемещения по большим массивам записей в компонентах отображения данных и без вызова обработчика события перемещения по записям. Для реализации быстрого перемещения по наборам данных можно использовать методы Disable Controls и Enable Controls/ Объект поля Назначение класса TField, как базового класса поля, заключается в умении взаимодействовать с компонентом отображения данных для обеспечения правильной визуализации данных. Например объект поля хранит способ выравнивания, параметры шрифта, текст заголовка и т.д., визуализацией полей набора данных можно управлять и другими средствами Свойства полей можно задать в словаре данных.
С точки зрения набора данных объект поля является хранилищем текущего значения этого поля (а не всего столбца данных) . Класс TField Тесно интегрирован с компонентами доступа к данным.
1. Динамические и статические поля. Поля могут быть динамическими и статическими. По умолчанию все объекты полей являются статическими, т.е. создаются программой автоматически после набора данных вез участия программиста.
Разработчик может создавать статистические поля. При этом можно использовать только необходимые поля, а также создавать объекты для несуществующих полей и в дальнейшем работать с ними как с реальными полями. Также механизм работы с постоянными полями обеспечивает создание вычислимых полей и полей синхронного просмотра.
Вычисляемые поля. Существуют только во время работы программы, когда открыт набор данных. Обычно они содержат результаты выполнения некоторых операций над несколькими другими полями.
Фильтрация данных
Наиболее эффективным способом отбора записей в набор данных (особенно из больших таблиц) является создание и выполнение соответствующего запроса SQL.
В случае, если набор данных функционирует на базе компонента Ttable используют встроенный в компонент механизм фильтрации данных.
Текст фильтра должен содержаться в свойстве Filter, а свойство Filtered включает и выключает фильтр. Параметры фильтра определяются свойством FilterOptions.
Эти свойства уже присутствуют в базовом классе TdataSet, однако в нем работают только методы присваивания значений для этих свойств. Сам механизм фильтрации включен в класс TBDEDatSet, так как BDE производит фильтрацию данных для их передачи в компонент приложения.
Компонент Tquery также может использовать фильтры. Это позволяет решать некоторые проблемы, которые иначе требует изменение текста запроса.
При использовании фильтра его текст транслируется BDEв синтаксис SQL и передается для выполнения на сервер или через соответствующий драйвер в локальную СУБД.
Фильтры можно создавать двумя способами:
- при помощи свойства Filter;
- для создания более сложных фильтров с применением средств языка программирования применяется метод-обработчик набора данных OnFilterRecord.
Также фильтры можно разделять на статистические и динамические.
Статистические фильтры создаются во время разработки приложения. Динамические фильтры можно создавать и редактировать во время выполнения приложения.
При создании текста фильтра для свойства Filter используются для полей соответствующей таблицы БД, а для задания отношений между ними применяются все операторы сравнения и логические операторы AND, OR, NOT.
Нельзя сравнивать между собой два поля.
Параметры фильтра определяются свойством FilterOptions, который может принимать следующие значения: foCaseInsenSitive – отключает сравнение строковых значений с учетом регистра символов; FoNoPatialCompare – отключает отбор строковых значений по заданной части строки.
Важнейшее преимущество метода OnFilterRecord по сравнению со свойством Filter состоит в том, что он позволяет сравнивать между собой поля и производить вычисления с их значениями.
Такой фильтр можно модифицировать путем присвоения методу процедурной переменной, содержащей ссылку на новый метод.
Закладки
Закладки, как инструмент работы с записями набора данных, позволяю быстро перемещаться на нужную запись. Механизм заплаток инкапсулирован уже в базовом классе TdataSet, но все основные методы для работы с закладками перекрыты в классе TBDEDataSet, так как именно обеспечивает их функционирование.
Набор данных может содержать неограниченное число закладок, каждая из которых представляет собой указатель. Закладку можно создать только для текущей записи набора данных.
При работе с закладками используются три основных метода: GetBookmark – создает новую закладку для текущей записи; GotoBookmark – осуществляет переход к заплатке, переданной в параметре; FreeBookmark – удаляет закладку, переданную в параметре.
Кроме того, можно, использовать метод BookmarkValid, который проверяет, указывает ли закладка на реально существующую запись и метод CompareBookmark, который позволяет сравнить между собой две закладки. В классе набора данных имеется свойство Bookmark, которое содержит название текущей закладки.
Примечание механизм закладок также используется в компоненте TDBGrid. Сетка имеет свойство SelecntdRows типа TbookmarkList, которое представляет свой список закладок, указывающих на одновременно выделенные записи.
Индексация данных
Важнейшей проблемой для любой БД является достижение максимальной производительности и ее сохранение при дальнейшем объемов хранимых данных. Использование индексов решает эту задачу.
Индекс представляет собой часть базы данных, в которой содержится информация об организации данных в БД. В отличие от ключей, которые просто идентифицируют отдельные записи, индексы занимают дополнительные объемы памяти и могут храниться как совместно с таблицей, так и в виде отдельных файлов. Индексы обновляются при модификации данных. При этом обновление индекса может требовать значительных ресурсов, поэтому есть смысл ограничить число индексов для таблиц, в которых происходит частое обновление данных.
С некоторым упрощением можно сказать, что индекс содержит уникальные идентификаторы записей и дополнительную информацию об организации данных. Поэтому если при выполнении запроса сервер или локальное СУБД обращаются для отбора записи к индексу, то это занимает значительно меньше времени, так как идентификатор гораздо меньше самой записи. Кроме того, индекс может ускорять обработку за счет объединения записей в группы по сходным значениям параметров.
Создание эффективного набора индексов для БД является нетривиальной задачей. Каждый индекс должен содержать только необходимые поля, при этом большую роль играет их упорядочивание.
Свойства и методы для работы с индексами присутствуют только в классе VCL Delphi Ttable, так как в компоненте TQuery работа с индексами осуществляются средствами SQL. Следовательно, в ближайшем общем предке – классе TBDE DataSet – отсутствуют возможности для использования индексов.
При открытии набора данных все записи отсортированы в соответствии с первичным ключом, но только в случае, если свойство DefaultIndex имеет значение True.
Чтобы подключить к набору данных вторичный индекс, необходимо присвоить свойству IndexName название индекса.
Альтернативный способ задания индекса заключается в использовании свойства IndexFieldNames, в котором задается перечень имен полей необходимого индекса, разделенных точкой с запятой. При этом в инспекторе объектов для этого свойства список полей для существующих индексов создается автоматически, разработчику остается только сделать выбор. Это свойство используется при задании индексов для таблиц серверов SQL.
Список имен всех индексов таблицы можно получить при помощи метода GetIndexNames.
Информация об индексах набора данных содержится в свойстве Items класса TIndexDefs. В нем для каждого индекса создается структура TIndexDef.
Написание индексов (наряду с написанием полей) используются при создании новых таблиц БД. Для каждого планируемого индекса перед необходимо создать (или скопировать из существующего набора данных) соответствующее описание. Тогда при создании таблицы будут добавлены автоматически.
Диапазоны
В компоненте TTable помимо фильтров имеется еще одно средство отбора записей в набор данных. Группа методов позволяет на основе использования индексов отбирать в набор данных только те записи, значения индексированных полей которых (для текущего индекса) соответствуют диапазону заданных величин.
Диапазоны работают быстрее фильтров. При использовании диапазонов набор данных обязательно должен находиться в состоянии dsSetKey.
Чтобы включить диапазон, необходимо задать стартовое и конечное значение диапазона для ключевых полей, затем применить заданный диапазон к набору данных. Работающий диапазон можно модифицировать. Все методы работы с диапазонами используют те поля, которые заданы в текущем индексе (IndexName, IndexFieldNames) .
Метод Назначение |
SetRangeStart Переводит набор данных в режим dsSetKey для задания начальной и конечной таблицы диапазона SetRangeEnd |
ApplyRange Применяет диапазон к набору данных CancelRange отменяет диапазон |
Для одновременного задания верхней и нижней границы можно использовать SetRange. Какая граница будет у диапазона – открытая или закрытая, определяет свойство KeyExclusive.