СЗамечание^
Состав компонентов можно настроить в диалоговом окне Palette Properties (Свойства палитры), вызываемом командой Properties (Свойства) контекстного меню Палитры компонентов. Здесь приводен состав Палитры компонентов, который получается после установки Delphi 7.
На странице Data Access (рис. 2.3) находятся невизуальные компоненты, предназначенные для организации доступа к данным:
□ DataSource (источник данных);
□ ciientDataSet (клиентский набор данных);
□ DataSetProvider (провайдер набора данных);
□ xml Transform (преобразователь документа XML в пакет данных и обратно);
□ xml TransformProvider (провайдер данных для преобразования документа XML);
□ xml Transformciient (адаптер между документом XML и провайдером).
Рис. 2.З. Страница Data Access Рис. 2.4. Страница Data Controls
На странице Data Controls (рис. 2.4) расположены визуальные компоненты, предназначенные для управления данными:
□ DBGrid (сетка, или таблица);
□ DBNavigator (навигационный интерфейс);
□ DBText (надпись);
□ DBEdit (однострочный редактор, или поле редактирования);
□ DBMemo (многострочный редактор, или панель редактирования);
□ DBimage (графическое изображение);
□ DBListBox(список);
□ DBComboBox (комбинированный список);
Глава 2. Реляционные базы данных и средства работы с ними
37
П DBCheckBox (флажок);
□ DBRadioGroup (группа переключателей);
□ DBLookupListBox (список, формируемый по полю другого набора данных);
□ DBLookupComboBox (комбинированный список, формируемый по полю другого набора данных);
□ DBRichEdit (полнофункциональный тестовый редактор, или поле редактирования);
□ DBCtriGrid (модифицированная сетка);
□ DBChart (диаграмма).
На странице dbExpress (рис. 2.5) размещены компоненты, предназначенные для соединения приложений с базами данных с помощью bdExpress:
|
□ SQLConnection (инкапсуляция bdExpress-соединения с сервером БД);
□ SQLDataSet (однонаправленный набор данных);
□ SQLQuery (однонаправленный набор данных Query);
□ SQLStoredProc (вызов хранимой процедуры сервера);
□ SQLTable (набор данных Table);
□ SQLMonitor (монитор выполнения SQL-запросов);
□ simpieDataSet (клиентский набор данных).
Рис. 2.5. Страница dbExpress Рис. 2.6. Страница DataSnap
Страница DataSnap (рис. 2.6) содержит компоненты, предназначенные для создания многоуровневых приложений:
□ DCOMConnection (управление соединением клиентских приложений DCOM с удаленным сервером);
□ Socketconnection (сокет Windows для управления соединением с сервером приложения);
□ simpieObjectBroker (обслуживание списка доступных серверов приложения для компонента соединения);
□ webConnection (управление соединением с сервером приложения по протоколу HTTP);
□ connectionBroker (централизация соединения с сервером приложения множества клиентов);
38
Часть I. Основы работы с базами данных
П sharedConnection (разделяемое соединение, управляющее соединением с дочерним удаленным модулем данных);
□ Locaiconnection (соединение между клиентским набором данных или по
средником XML и провайдером).
Страница BDE (рис. 2.7) стала включать на один компонент меньше и содержит компоненты, предназначенные для управления данными с использованием BDE:
□ таЫе (набор данных, основанный на таблице БД);
□ Query (набор данных, основанный на SQL-запросе);
□ storedProc (вызов хранимой процедуры сервера);
□ DataBase (соединение с БД);
□ Session (текущий сеанс работы с БД);
□ BatchMove (выполнение операций над группой записей);
□ updateSQL (изменение набора данных, основанного на SQL-запросе или хранимой процедуре);
|
□ NestedTabie (вложенная таблица).
На странице ADO (рис. 2.8) расположены компоненты, предназначенные для управления данными с использованием технологии ADO (Active Data Objects):
□ ADOConnection (соединение);
□ ADOCommand (команда);
□ ADODataSet (набор данных);
□ ADOTable (набор данных Table);
□ ADOQuery (набор данных Query);
□ ADOStoredProc (вызов хранимой процедуры сервера);
□ RDSConnection (соединение RDS).
.Snap | BDE ADO | InterBase ШЭ i?«i?Ш ЦШ1 ШЩ о* ЕШ
sg. ™°в ёЧ jj jjj *™5 ч»,
Рис. 2.7. Страница BDE Рис. 2.8. Страница ADO
СЗамечание^
Соединение RDS служит для управления передачей объекта Recordset от одного процесса (компьютера) к другому при создании серверных приложений.
На странице InterBase (рис. 2.9) находятся компоненты, предназначенные для работы с сервером InterBase:
□ iвтable (набор данных таЫе);
□ IBQuery (набор данных Query);
Глава 2. Реляционные базы данных и средства работы с ними
39
П iBStoredProc (вызов хранимой процедуры);
□ iBDatabase (соединение с БД);
□ iBTransaction (транзакция);
□ iBUpdateSQL (изменение набора данных, основанного на SQL-запросе);
□ iBDataSet (источник данных);
□ ibsql (выполнение SQL-запроса);
□ IBDatabaselnfo (информация О БД);
□ iBSQLMonitor (монитор выполнения SQL-запросов);
□ iBEvents (событие сервера);
□ iBExtract (извлечение данных);
□ iBCiientDataSet (клиентский источник данных).
Страница Decision Cube (рис. 2.10) содержит компоненты, предназначенные для построения систем принятия решений:
□ DecisionCube (куб многомерных данных);
□ DecisionQuery (набор, содержащий многомерные данные);
□ DecisionSource (источник многомерных данных);
□ DecisionPivot (двумерная проекция многомерных данных);
|
□ DecisionGrid (сетка для табличного представления многомерных данных);
□ DecisionGraph (графическое представление многомерных данных).
Рис. 2.9. Страница InterBase Рис. 2.10. Страница Decision Cube
И наконец, на странице Rave (рис. 2.11), которая заменила страницу QReport, находятся компоненты, предназначенные для построения отчетов:
□ RvProject (обеспечивает доступ к визуальным отчетам);
□ RvSystem (обеспечивает просмотр, печать и настройку параметров отчетов);
□ RvNDRWriter (обеспечивает хранение отчета в двоичном формате);
□ RvCustomConnection (служит для настройки способа передачи данных в отчет);
□ RvDataSetConnection (обеспечивает доступ к компонентам, производным от класса TDataSet);
□ RvTabieConnection (служит для доступа к компонентам типа ттаЫе или их наследникам;
□ RvQueryConnection (СЛУЖИТ ДЛЯ ДОСТупа К КОМПОНеНТаМ ТИПа TQuery ИЛИ ИХ
потомкам);
40
Часть I. Основы работы с базами данных
П RvRenderPreview (посылает отчет в двоичном формате для предварительного просмотра);
□ RvRenderPrinter (посылает отчет в двоичном формате на текущее устройство печати);
□ RvRvRenderPDF (преобразует поток или файл NDR (Rave snapshot report file, файл снимка отчета Rave) в формат PDF);
□ RvRenderHTML (преобразует поток или файл NDR в формат HTML);
□ RvRenderRTF (преобразует поток или файл NDR в документ RTF);
□ RvRenderRTF (преобразует поток или файл NDR в текстовый документ).
] Win 3.1 ] ActiveX Rave | Templates | Indv Clients] I ndu Servers ] Indu
RV RV RV RVE R\Ab Rrf R1 RV-> ili+ili ili-fili ===-■-==! ЩШ
ИШ 4t№ +P -?- -& -& -<£Д ~J -^ PDF HTML RTF TEXT
Рис. 2.11. Страница Rave
Имена многих компонентов, предназначенных для работы с данными, содержат префиксы, например, db, ib или rv. Префикс db означает, что визуальный компонент связан с данными и используется для построения интерфейсной части приложения. Такие компоненты размещаются в форме и предназначены для управления данными со стороны пользователя. Префикс Rv означает, что компонент используется для построения отчетов Rave. Префикс ib означает, что компонент предназначен для работы с сервером InterBase.
Исключения баз данных
В дополнение к основным исключениям, специально для операций, связанных с БД, система Delphi предоставляет следующие классы исключений:
□ EDatabaseError — ошибка БД; потомки этого класса:
• EDBEngineError — ошибка BDE (для локальных БД и сетевых БД архитектуры "файл-сервер");
• EDBClient — ошибка в приложении клиента (для сетевых БД архитектуры "клиент-сервер"); код ошибки возвращается BDE, ADO, dbExpress или другим механизмом доступа к данным;
• EUpdateError — ошибка, возникающая при обновлении записей;
□ EDBEditError — введенное в поле значение не соответствует типу поля.
Класс EDatabaseError предназначен для обработки ошибок, возникающих при выполнении операций с набором данных (класс TDataSet и его потомки, в первую очередь, ттаЫе и TQuery). Этот класс производится непосредственно от
Глава 2. Реляционные базы данных и средства работы с ними
41
класса Exception. Исключение класса EDatabaseError генерируется, например, при попытке открыть набор данных, связанный с отсутствующей таблицей, или изменить запись набора данных, который находится в режиме просмотра.
Класс EDBEngineError предназначен для обработки ошибок, возникающих при работе с процессором баз данных BDE на локальном компьютере. В дополнение
к свойствам, имеющимся у класса EDatabaseError, у класса EDBEngineError есть два новых свойства:
□ ErrorCount типа integer — содержит количество возникших исключений;
□ Errors [index: integer] типа TDBError — представляет собой список исключений, общее число которых указано свойством ErrorCount. Индекс index позволяет получить доступ к возникшему исключению по его номеру (нумерация начинается с нуля). На практике обычно анализируется первое из исключений (Errors [0]), указывающее основную причину ошибки.
Класс TDBError содержит информацию об исключении, определяемую следующими свойствами:
□ Message типа string (текст сообщения, характеризующего возникшую ошибку);
□ ErrorCode типа DBlResult (код ошибки), тип DBlResult соответствует типу
word;
□ Category типа Byte (категория исключения);
□ Subcode типа Byte (группа, или подкод, исключения);
□ NativeError типа Longint (код ошибки, возвращаемой сервером) — если значение этого свойства равно нулю, то исключение произошло не на сервере.
Код ошибки, определяемый значением свойства ErrorCode, имеет две составляющие: категорию и группу исключения, определяемые значениями свойств Category и Subcode соответственно. В категорию объединяются по признаку схожести несколько исключений. Группа уточняет исключение внутри категории.
Отметим, что для программной генерации исключений, обслуживаемых классами EDatabaseError и EDBEngineError, используются специальные методы DatabaseError и DBiError, рассматриваемые ниже.
Класс EDBClient отличается от класса EDBEngineError в основном тем, что предназначен для обработки ошибок, возникающих при работе с различными механизмами доступа к данным (не только с процессором баз данных BDE) в операциях с сетевыми базами архитектуры "клиент-сервер".
Генерируемые при работе с БД исключения обрабатывают глобальные и локальные обработчики, с которыми мы познакомимся немного позже. Кроме того, используемые для доступа к данным компоненты имеют специальные события для обработки исключений.
42
Часть I. Основы работы с базами данных
Например, для набора данных Table такими событиями являются:
□ OnEditError (ошибка редактирования или вставки записи);
□ OnPostError и OnUpdateError (ошибка закрепления изменений в записи);
□ OnDeleteError (ошибка удаления записи).
Использование подобных событий и программирование их обработчиков будут рассмотрены при изучении соответствующих компонентов.
Класс EDBEditError используется в случаях, когда вводимые в поле данные несовместимы с маской ввода, заданной с помощью свойства EditMask этого поля. Отметим, что для проверки вводимых в поле значений можно также использовать события OnSetText, OnValidate и OnChange. Примеры использования этих событий при программировании обработчиков приводятся в главе 5.
Приведем в качестве примера процедуру, в которой проводится анализ исключения, возникшего при работе с базой данных с помощью BDE.
procedure TForml.ButtonlClick(Sender: TObject); begin try if OpenDialogl.Execute then begin Tablel.Active:= False;
Tablel.TableName:= OpenDialogl.FileName; Tablel.Active:= True; end; except on EO: EDatabaseError do MessageDlg('Ошибка EDatabaseError! ',
mtError, [mbOK], 0); on EO: EDBEngineError do MessageDlg('Ошибка EDBEngineError! ', mtError, [mbOK], 0); else MessageDlg('Неопознанная ошибка!', mtError, [mbOK], 0); end; end;
При смене таблицы, связанной с набором данных Tablel, выполняются анализ и обработка возможного исключения. Исключение проверяется на принадлежность к одному из двух классов: EDatabaseError и EDBEngineError. Обработка заключается в выдаче сообщения о принадлежности исключения к одному из этих классов. Если исключение носит другой характер, то выдается сообщение о том, что оно не распознано.
Глава 3
Проектирование баз данных
Проектирование реляционной БД заключается главным образом в разработке структуры данных, т. е. в определении состава таблиц и связей между ними. При этом структура должна быть эффективной и обеспечивать:
□ быстрый доступ к данным;
□ отсутствие дублирования (повторения) данных;
□ целостность данных.
Проектирование структуры данных (структуры БД) также называют логическим проектированием, или проектированием на логическом уровне.
При проектировании структур данных можно выделить три основных подхода.
□ Сбор информации об объектах решаемой задачи в рамках одной таблицы (одного отношения) и последующее разбиение ее на несколько взаимосвязанных таблиц на основе нормализации отношений.
□ Формулирование знаний о системе (определение типов исходных данных и их взаимосвязей) и требований к обработке данных, а затем получение с помощью CASE-средств схемы БД или готовой прикладной информационной системы.
□ Структурирование информации в результате системного анализа на основе совокупности правил и рекомендаций.
Проектирование может выполняться классическим способом, когда разработчик собирает и выделяет объекты системы и их характеристики, после чего вручную приводит их к требуемой структуре данных. Кроме того, для проектирования можно использовать так называемые CASE-системы, которые автоматизируют процесс разработки не только БД, но и информационной системы в целом.
Нормализация базы данных
Нормализация БД — это процесс уменьшения избыточности информации в БД. Метод нормализации основан на достаточно сложной теории реляционных моделей данных. Рассмотрим основные особенности и технику нормализации, не вдаваясь в теоретическое обоснование этих вопросов.
Часть I. Основы работы с базами данных
Избыточность данных и аномалии
При разработке структуры БД могут возникнуть проблемы, связанные:
□ с избыточностью данных;
□ с аномалиями.
Под избыточностью данных понимают дублирование данных, содержащихся в БД. При этом различают простое (не избыточное) дублирование и избыточное дублирование данных.
Избыточность данных при выполнении операций с ними может приводить к различным аномалиям — нарушению целостности БД. Выделяют аномалии:
□ удаления;
□ обновления;
□ ввода.
Не избыточное дублирование является естественным и допустимым, его примером является список телефонов (местных) сотрудников организации, показанный в табл. 3.1.
Три сотрудника имеют одинаковый номер телефона 123, что возможно, например, в случае, когда они находятся в одной комнате. Таким образом, номер телефона в таблице дублируется, однако для каждого сотрудника этот номер является уникальным. В случае удаления одного из дублированных значений номера телефона (удаления соответствующей строки таблицы) будет потеряна информация о сотруднике — Иванове П. Л., Петрове А. Ф. или Васине И. Г., — что является аномалией удаления.
При смене номера телефона в комнате его необходимо изменить для всех сотрудников, которые в ней находятся. Если для какого-либо сотрудника этого не сделать, например, для Петрова А. Ф., то возникает несоответствие данных, связанное с аномалией обновления.
Аномалия ввода заключается в том, что при вводе в таблицу новой строки для ее полей могут быть введены недопустимые значения. Например, значение не входит в заданный диапазон или не задано значение поля, которое в обязательном порядке должно быть заполнено (не может быть пустым).
Глава 3. Проектирование баз данных
45
Теперь приведем пример избыточного дублирования данных. Список телефонов дополнен номерами комнат, в которых находятся сотрудники (табл. 3.2). При этом номер телефона указан только для одного из сотрудников — в примере для Иванова П. Л., который находится в списке первым. Вместо номеров телефонов других сотрудников этой комнаты поставлен прочерк. На практике кодировка прочерка зависит от особенностей конкретной таблицы, например, можно обозначать прочерк значением Null.
Таблица 3.2. Пример избыточного дублирования данных
Сотрудник Комната Телефон
Иванов П. Л. 17 123
Петров А. Ф. 17 —
Сидоров О. Е. 22 456
Кузнецова В. А. 8 789
Васин И. Г. 17 -
Однако при таком построении таблицы появляются проблемы.
□ Номер телефона произвольного сотрудника можно получить только путем поиска в другом столбце таблицы (по номеру комнаты).
□ При запоминании таблицы для каждой строки отводится одинаковая память вне зависимости от наличия или отсутствия прочерков.
□ При удалении строки с данными сотрудника, для которого указан номер телефона комнаты, будет утеряна информация о номере телефона для всех сотрудников из этой комнаты.
Если вместо прочерков указать номер телефона, то избыточное дублирование все равно остается. От него можно избавиться, например, с помощью разбиения таблицы на две новых (табл. 3.3 и 3.4). Разбиение — это процесс деления таблицы на несколько таблиц с целью поддержания целостности данных, т. е. устранения избыточности данных и аномалий. Таблицы связаны между собой по номеру комнаты. Для получения информации о номере телефона сотрудника из первой таблицы по фамилии сотрудника нужно считать номер его комнаты, после чего из второй таблицы по номеру комнаты считывается номер телефона.
Рассмотренное разбиение таблицы на две является примером нормализации отношений. При этом избыточность данных уменьшилась, однако одновременно увеличилось время доступа к ним. Для получения номера телефона сотрудника теперь необходимо работать с двумя таблицами, а не с одной, как в предыдущем случае.
46
Часть I. Основы работы с базами данных
Приведение к нормальным формам
Процесс проектирования БД с использованием метода нормальных форм является итерационным (пошаговым) и заключается в последовательном переводе по определенным правилам отношений из первой нормальной формы в нормальные формы более высокого порядка. Каждая следующая нормальная форма ограничивает определенный тип функциональных зависимостей, устраняет соответствующие аномалии при выполнении операций над отношениями БД и сохраняет свойства предшествующих нормальных форм.
Выделяют следующую последовательность нормальных форм:
□ первая нормальная форма;
□ вторая нормальная форма;
□ третья нормальная форма;
□ усиленная третья нормальная форма, или нормальная форма Бойса-Кодда;
□ четвертая нормальная форма;
□ пятая нормальная форма.
Проектирование начинается с определения всех объектов, информация о которых должна содержаться в БД, и выделения атрибутов (характеристик) этих объектов. Атрибуты всех объектов сводятся в одну таблицу, которая является исходной. Затем эта таблица последовательно приводится к нормальным формам в соответствии с их требованиями. На практике обычно используются первые три нормальные формы.
Для примера спроектируем БД для хранения информации о футбольном чемпионате страны. Будем запоминать информацию о дате матча, игравших командах и забитых голах. Сначала объединим все данные в одну исходную таблицу, имеющую следующую структуру (поля):
дата матча; команда хозяев; команда гостей; игрок, забивший гол;
Глава 3. Проектирование баз данных
47
П признак команды;
□ время гола.
В качестве данных о команде (хозяев и гостей) укажем ее название, город и фамилию тренера, что однозначно идентифицирует любую команду. Для игрока, забившего гол, будем указывать фамилию, а для обозначения его принадлежности к той или иной команде используем признак, например, х — для команды хозяев, а г — для команды гостей. Время гола представляет число минут, прошедших с начала матча.
Приведенная таблица имеет относительно простую структуру, на практике подобные таблицы содержат также данные о составах команд, арбитрах, времени начала игры, числе зрителей, нарушениях правил, заменах, предупреждениях и удалениях игроков и другую информацию. В структуре таблицы указаны только названия полей, поскольку тип и размерность полей на этом этапе большого значения не имеют.
Созданную таблицу можно рассматривать как однотабличную БД. Ее главным недостатком является значительная избыточность данных. Так, для каждого игрока, забившего гол, указываются дата матча и информация о команде хозяев и гостей. Дублирование данных способно привести к аномалиям, а также к существенному увеличению размера базы.
Отметим, что в таблице отсутствует информация о счете матча, т. к. ее можно получить, подсчитав голы, забитые хозяевами и гостями. Побочным явлением такого подхода является то, что если в матче не было забитых голов, то информация о соответствующем матче в таблице отсутствует. Эта ситуация исправляется автоматически при последующем разбиении исходной таблицы на таблицы матчей и голов.
Первая нормальная форма
Приведем исходную таблицу к первой нормальной форме, для которой должны выполняться следующие условия:
□ поля содержат неделимую информацию;
□ в таблице отсутствуют повторяющиеся группы полей.
Во втором и третьем полях исходной таблицы содержится информация о названии команды, городе и тренере, например, зенит Санкт-Петербург ю.морозов. Это противоречит первому требованию — информация о команде, городе и тренере является делимой. Эта информация может и должна быть разделена на три отдельных поля — название команды, город, фамилия тренера.
Согласно второму требованию, в таблице должны отсутствовать повторяющиеся группы полей, т. е. группы, содержащие одинаковые функциональные значения. В исходной таблице таких групп нет, поэтому второму требованию она удовлетворяет. Может показаться, что повторяющимися группами полей являются поля с информацией о командах хозяев и гостей. Несмотря на то, что состав и определения названных полей полностью совпадают, эти поля имеют различное функциональное назначение и не считаются повторяющимися.
48
Часть I. Основы работы с базами данных
Примером таблицы, имеющей повторяющиеся группы полей, может служить табл. 3.5 с результатами экзаменационной сессии. В этой таблице для оценок, полученных студентами на экзаменах, необходимо создать столько полей, сколько может быть различных предметов. В связи с тем, что студент сдает не все экзамены (для них проставлены прочерки), размер записей и таблицы в целом неоправданно увеличивается. Кроме того, значительные трудности создает изменение состава предметов. Если организовать переименование предмета достаточно просто, то его удаление или добавление требует изменения структуры таблицы, что, вообще говоря, крайне нежелательно, поскольку структура таблицы обычно определяется еще на этапе проектирования БД.
Таблица 3.5. Результаты экзаменационной сессии
Студент Математика Информатика Физика История Английский
язык
Семенов Р. О. 4 4 4 p 4
Костина В. К. 4 3 3 p 4
Папаев Д. Г. 5 5 5 p p
Симонов П. С. p p p 4 4
Вторая и третья нормальные формы касаются отношений между ключевыми и не ключевыми полями.
Вторая нормальная форма
Ко второй нормальной форме предъявляются следующие требования:
□ таблица должна удовлетворять требованиям первой нормальной формы;
□ любое не ключевое поле должно однозначно идентифицироваться ключевыми полями.
Записи таблицы, приведенной к первой нормальной форме, не являются уникальными и содержат дублированные данные. Так, если за одну минуту футболист забил несколько голов, то таблица будет содержать одинаковые записи. Чтобы обеспечить уникальность записей, введем в таблицу поле ключа — код матча. При этом значение ключа будет однозначно определять каждую запись таблицы.
Тогда структура таблицы примет такой вид:
□ Код матча (уникальный ключ)
□ Дата матча
□ Название команды хозяев
□ Город команды хозяев
□ Фамилия тренера команды хозяев
□ Название команды гостей
□ Город команды гостей
Глава 3. Проектирование баз данных
49
П Фамилия тренера команды гостей
□ Игрок
□ Признак команды
□ Время гола
Записи этой таблицы имеют значительное избыточное дублирование данных, т. к. дата матча, а также информация о командах указываются для каждого гола. Поэтому разобьем таблицу на две таблицы, одна из которых будет содержать данные о матчах, а вторая — о голах, забитых в каждом конкретном матче. Структуры этих таблиц будут следующими.
Поля таблицы матчей:
□ Код матча (уникальный ключ)
□ Дата матча
□ Название команды хозяев
□ Город команды хозяев
□ Фамилия тренера команды хозяев
□ Название команды гостей
□ Город команды гостей
□ Фамилия тренера команды гостей
Поля таблицы голов:
□ Код гола (уникальный ключ)
□ Код матча
□ Игрок