Введение

Архангельский Андрей

       Толчком к разработке и исследованию древовидных структур послужила статья Дмитрия Кузменко (http://www.ibase.ru) с таким же названием. При всей полезности статьи Д.Кузменко, проблема оказалась много шире и применение древовидных структур в БД открывает новые функциональные возможности.
       Во-первых, есть множество применений древовидных структур даже без использования древовидных отображений.
       Во-вторых, есть различные варианты построения древовидных структур как на одной таблице, так и на двух, каждый из которых имеет свои преимущества и недостатки. Не всегда первое, пришедшее в голову решение, является самым удачным. Поэтому приведены различные решения одной и той же задачи с анализом преимуществ и недостатков каждого решения.
       В-третьих, есть модель смежных вершин и модель вложенных множеств, которую пропагандирует Джо Селко. В каких случаях какую модель выбирать можно понять только после полного исследования обоих моделей.
       И, наконец, так как дерево является частным случаем графа, то необходимо также рассмотреть задачи с произвольными графами.
       И в каждом случае необходимо рассмотреть все функции, которые возможны, начиная от отображения до суммирования. При этом не нужно забывать, что базу данных нужно собрать, а значит в состав рассматриваемых функций нужно включить и вывод фрагмента таблицы в SQL-скрипт.
       Так или иначе, но в каждом проекте встречалась задача связанная с древовидными структурами. С каждым проектом в книгу добавлялся соответствующий раздел и пример, демонстрирующий найденное решение. Таким образом получилась коллекция различных задач и их решений так или иначе связанных с древовидными структурами. Решения систематизированы от простых к сложным.
       Так как древовидные структуры как правило отображают ту или иную классификацию, то в приложении рассматрены проблемы, которые встречаются при попытке перенести наиболее известные классификации в базу данных.

 

Используемые инструменты

  Указания исполнителю: Не поддавайтесь отчаянию и страху, даже если тринадцатая попытка оказалась неудачной! Подобные программы называются интроспективными, и существует теорема, в которой утверждается, что интроспективную программу можно написать на любом "достаточно мощном" языке. Все обычные языки программирования — достаточно мощные.
       Чарльз Уэзерелл "Этюды для программистов"

       Реальные разработки велись с помощью Borland Delphi 2006, Firebird 2.0, IBObjects 4.7, Raize Components 5.0. Предыдущая версия написана с помощью Borland Delphi 7, Firebird 1.53, IBObjects 4.3, Raize Components 4.0. Поэтому возможны некоторые особенности реализации кодов.
       Был большой соблазн сделать все примеры на базе Turbo Delphi Explorer и InterBase 7.5 Developer Edition, с тем чтобы читатель мог попробовать все примеры без дополнительных затрат. Но библиотека IBX исключена из Explorer-версии, а библиотека dbExpres не имеет двунаправленных курсоров, что не позволяет использовать TDBGrid.
       С другой стороны, имеется несколько библиотек прямого доступа к серверу InterBase/Firebird, работа с которыми имеет существенные различия. К ним относятся:
       InterBaseXpress (IBX) — содержит компоненты с открытыми исходными текстами для работы с базой данных и выполнения сервисных функций, которые поставляются с некоторыми продуктами Borland, такими как Delphi, Kulix, C++ Builder. Входит в состав Delphi 7, Delphi 2006 — вкладка Interbase.
       IBObjects — объединяет две давно известные системы компонентов для Firebird и InterBase, которые позволяют разработчикам использовать инструменты Borland IDE (Delphi, Kulix, C++ Builder) для реализации всех возможностей Firebird. Одна система совместима с библиотеками Borland TDataset и другими компонентами сторонних разработчиков, которые наследуют архитектуру TDataset. Другая, известная как "родная IBO", включает собственный класс источников данных (data source) и множество управляющих элементов для управления данными. IBO4_6_B_Eval.zip можно найти на прилагаемом компакт-диске. За дополнительной информацией обращайтесь на http://www.ibobjects.com.
       FIBPlus — мощный набор компонентов для Delphi, Kulix и C++ Builder основан на архитектуре Borland TDataset и предоставляет полную совместимость со многими компонентами коммерческого характера и открытыми кодами. Он предоставляет простой способ преобразования компонентов Borland InterBaseXpress. За дополнительной информацией обращайтесь на http://www.devrace.com.
       Таким образом, все примеры написаны и оттестированы в Delphi 2006 с использованием трех вышеописанных библиотек. Каталоги с проектами примеров имеют вид:
       ExampleXX — для библиотеки InterBaseXpress (IBX),
       ExampleXXIBO — для библиотеки IBObjects (IBO),
       ExampleXXFIB — для библиотеки FIBPlus,
       — где XX номер примера.
       Для некоторых примеров требуются компоненты Raize Components 5.0, которые отсутствуют в стандартной поставке Delphi. В этих случаях используются фрагменты рабочих проектов, созданных на базе IBObjects.
       Для получения дополнительной информации обращайтесь на http://www.raize.com.

Где взять Firebird
       Все примеры построены на базе СУБД Firebird, доброй рабочей лошадки, которая и "хлеба не просит" (бесплатная), и работает надежно, и хлопот никаких — поставил и забыл.
       Основной ресурс, на котором лежат все версии СУБД Firebird (включая исходные тексты), находится по адресу:
       http://sourceforge.net/project/showfiles.php?group_id=9028
       Кроме того существует много полезных ресурсов, посвященных Firebird:
       http://www.firebirdsql.org/ — сайт команды разработчиков Firebird.
       http://www.firebirdnews.org/ — сайт новостей от разработчиков Firebird.
       http://www.ibase.ru/ — фирма ibase и русское сообщество пользователей Firebird,
       http://www.ibprovider.com/ — разработчики OLE DB кормпонентов доступа к Firebird
       http://www.sqlly.com/ — разработчик InterBase/Firebird Development Studio — мощного инструмента для разработчика баз данных под управлением серверов InterBase или Firebird.

Конференции
       Существует масса конференций, где есть возможность обсудить аспекты работы Firebird на русском и английском языках.
       web-форум forum.ibase.ru
       web-форум www.sql.ru
       groups.google.com/group/ru-firebird?lnk=oa - конференция по Interbase/Firebird, организованная на смену epsylon.public.interbase. Доступна в режиме чтения, и read/write - после регистрации.
       Firebird Tracker - баг-трекер
       Почтовые конференции и списки рассылки проекта Firebird:
       firebird-checkins - автоматическая рассылка diff при изменении исходных текстов проекта
       firebird-devel - обсуждение вопросов разработки
       firebird-doc - обсуждение вопросов по документации
       firebird-net-provider - вопросы по драйверу .Net
       firebird-odbc-devel - вопросы по драйверу ODBC
       firebird-test - обсуждение тестов
       firebird-website - обсуждение firebirdsql.org

 

Построение Базы Данных

       База данных для тестирования примеров представлена в виде SQL-скриптов. Почему?
       — смотри замечательную книгу Хелен Борри "Firebird. Руководство разработчика баз данных", СПб., БХВ-Петербург, 2006г (стр.258-267),
       — скрипты позволяют собрать БД с нуля под любой сервер и легко исправить возникшие или старые ошибки. Так моей практике был случай, когда достаточно большая БД "не захотела" мигрировать из FB1.53 в FB2.0 через backup/restore из-за ошибки в структуре, которая игнорировалась FB1.53 и проявилась только в FB2.0;
       — не всегда можно изменить структуру БД с помощью таких инструментов как EMS IBManager или IBExpert. Из практики: Необходимо было поменять тип данных в простой пустой таблице, но в поле primary key, с которым было связано более 20 таблиц и множество процедур. Для изменения с помощью IBExpert потребовалось бы удалить связи с таблицами, изменить тип данных, восстановить связи. Это потребовало бы не только много времени, но и вероятность ошибки была бы велика. Кстати, ошибка в предыдущем случае была допущена с помощью EMS IBManager;
       — скрипты позволяют вести модульную разработку и собирать различные БД для конкретных применений;
       — и, наконец, если Вы что-то можете сделать с помощью SQL-скриптов, то Вы сможете сделать это в любой программе. Обратное положение не всегда верно.
       Все скрипты создания БД находятся в каталоге FB_SQL на прилагаемом компакт-диске. Структура каталога следующая:
       — в корне находятся файлы DBCreate.doc, DBCreate.txt, FillengDB.bat и isql.exe. Причем файл isql.exe помещен в этот каталог только для удобства построения командного файла. Правильную версию можно взять из каталога bin установленного у Вас сервера Firebird/InterBase. Другой способ упростить командный файл — это добавить путь к каталогу Firebird/Bin (Interbase/Bin) установленного у вас сервера к переменной PATH.
       — в подкаталоге dat содержатся SQL-скрипты для заполнения таблиц данными. Название каждого скрипта начинается с наименования таблицы, данные для которой в нем содержаться. Для некоторых таблиц может быть несколько скриптов.
       — в подкаталоге res сохраняются результаты выполнения скриптов, для дальнейшего анализа и поиска ошибок.
       Основной скрипт содержится в файле DBCreate.doc, что позволяет его легко редактировать, использовать навигацию Microsoft Word, собирать оглавление и распечатывать в удобном формате. Для того, чтобы получить рабочий SQL-скрипт достаточно файл DBCreate.doc сохранить в текстовом формате. Для построения рабочей БД необходимо закрыть все приложения, которые используют подключение к текущей БД, и запустить коммандный файл FillengDB.bat.
       Те примеры, которые отсутствуют в исходниках, взяты из реальных разработок, поэтому имена компонентов и переменных не изменялись.

Подключение к базе данных

       Для использования примеров создайте на своем компьютере каталог и скопируйте в него все примеры с прилагаемого компакт-диска. В этом каталоге будет создаваться БД и там же примеры будут искать БД в виде файла DB_Tree2.fb.
       Во всех примерах подключение к БД происходит примерно одинаково.
       Для примеров на базе компонентов IBX подключение выполняется следующим образом:

procedure TForm1.FormCreate(Sender: TObject);
Var
   db : String;
   ps : Integer;
begin
   IBDatabase1.Connected := False;
   db := ExtractFilePath(Application.ExeName);
   db := ReverseString(db);  Delete(db,1,1); // удалить \
   ps := Pos('\',db);  Delete(db,1,ps);      // найти следующий \ и удалить
   db := ReverseString(db)+'\DB_Tree2.fb';   // перевернуть строку и добавить БД
   IBDatabase1.DatabaseName := db;
   IBDatabase1.Connected := True;
end;

       Сначала разрывается соединение, если оно есть. Дело в том, что при использовании компонентов IBX возникает неприятная систуация. Если редактируются какие-либо свойства Query, то автоматически устанавливается соединение с БД. После путешествия по остальным компонентам, про установленное соединение можно просто забыть. Поэтому после построения проекта возможна ситуация, когда приложение начинает подключаться к БД без соответствующих параметров. Для исключения этого и введено принудительное отключение от БД.
       Дальше вычисляется путь к БД. Для этого определяется путь к приложению, удаляется один уровень каталогов из пути и добавляется имя БД.
       Имя БД записывается в свойство DatabaseName компонента IBDatabase1 после чего устанавливается соединение.
       Login и Password во всех примерах установлен явно и имеет значения:
       Login = SYSDBA,
       Password = masterkey.
       Т.е. значения по умолчанию для Interbase и Firebird.
       Для примеров на базе компонентов IBO имеются незначительные изменения:

procedure TForm1.FormCreate(Sender: TObject);
Var
   db : String;
   ps : Integer;
begin
   IB_Connection1.Disconnect;
   db := ExtractFilePath(Application.ExeName);
   db := ReverseString(db);  Delete(db,1,1);
   ps := Pos('\',db);  Delete(db,1,ps);
   db := ReverseString(db)+'\DB_Tree2.fb';
   IB_Connection1.DatabaseName := db;
   IB_Connection1.Username := 'SYSDBA';
   IB_Connection1.Password := 'masterkey';
   IB_Connection1.Connect;

end;

       Разница только в том, что для подключения к БД используется компонент IB_Connection1 и имя пользователя и пароль записываются в процедуре FormCreate.

 

Отладка программ с запросами


       В некоторых примерах включены дополнительные операторы для отладки запросов к БД. Используемая система выводит в протокол ту информацию, которую программист указал в этих операторах. Для включения/выключения системы отладки необходимо:
       — открыть диалог "Project options";
       — найти вкладку "Directories/Conditionals";
       — на этой вкладке найти панель "Conditionals" и в поле Conditional defines записать (удалить) переменную AZDEBUG.
       Для работы этой системы отладки в текст программы для каждого проекта внесены следующие строки:

var
{$IFDEF AZDEBUG} flError : TextFile; {$ENDIF}

       — определяет переменную для файла протокола.

procedure TForm1.FormCreate(Sender: TObject);
Var
   db : String;
begin
{$IFDEF AZDEBUG}
  db := ExtractFilePath(Application.ExeName)+'Example08_err.txt';
  AssignFile(flError,db); 
  ReWrite(flError);  
  WriteReprtText('<<< Example 08  Start >>>');
{$ENDIF}

       — определяется имя файла протокола, которое представляет собой имя файла приложения с добавлением '_err' и имеет расширение .txt. Первой в файл протокола выводится строка обозначающая начало работы.
       Для вывода информации используются две процедуры:

{$IFDEF AZDEBUG}
procedure TForm1.WriteReprtText(txt : String);
begin
  WriteLn(flError,txt);   Flush(flError);
end;

       Первая процедура WriteReportText просто выводит текст, который указан во входной переменной txt. Типичное использование — в начале каждой процедуры полезно вставить вызов процедуры WriteReportText, переменная txt которой содержит название процедуры.

procedure TForm1.WriteReprtStrings(Name: String; Str : TStrings);
Var
  cn : Integer;
begin
  WriteLn(flError,'+>>>'+Name+':');
  For cn:=0 to Str.Count-1 do Begin
      writeln(flError,Str.Strings[cn]);
  end;
  WriteLn(flError,'->>>');      Flush(flError);
end;
{$ENDIF}

       Вторая процедура WriteReportStrings выводит в файл протокола массив строк, например, Query.SQL, который процедура оформляет дополнительными строками указывающими на имя массива строк и признаками начала и конца этого массива.
       Ниже приведен пример использования этих процедур:

procedure TForm1.tvGoodsExpanding(Sender: TObject; Node: TTreeNode;
                                  var AllowExpansion: Boolean);
Var
   RowChild : Integer;
   z : Integer;
   sFld,sCod : String;
   ChildNode,NewNode : TTreeNode;
begin
  inherited;
{$IFDEF AZDEBUG} WriteReprtText('TForm1.tvGoodsExpanding'); {$ENDIF}
  If isNoClose then begin
     If Node.HasChildren then begin
        Node.DeleteChildren; z := Node.ImageIndex;
        qrTVGoods.Close;  qrTVGoods.SQL.Clear;
        qrTVGoods.SQL.Add(sqlSelect);
        qrTVGoods.SQL.Add(sqlWhere+IntToStr(z));
        qrTVGoods.SQL.Add(sqlOrder);
{$IFDEF AZDEBUG} WriteReprtStrings('qrTVGoods.SQL',qrTVGoods.SQL);{$ENDIF}
        qrTVGoods.Open;   qrTVGoods.First;
. . . . .
end;

       Вызов процедуры WriteReportString должен выполняться до выполнения qrTVGoods.Open, с тем чтобы ошибки в запросе не помешали вывести его в файл протокола. Вызов процедуры WriteReportText в данном случае позволяет отследить последовательность событий, которые возникают при работе программы.
       Для завершения системы отладки необходимо закрыть файл протокола в процедуре FormClose:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   IBDatabase1.Connected := False;
{$IFDEF AZDEBUG} WriteReprtText('<<< Example05  End >>>');  {$ENDIF}
{$IFDEF AZDEBUG} CloseFile(flError); {$ENDIF}
end;

 

Что находится на прилагаемом компакт-диске

Прилагаемый компакт-диск содержит, кроме БД, примеры и дополнительное программное обеспечение. Структура диска следующая:

DB_TREE.FB  - БД построенная под Firebird 2.0
FB_SQL      - Каталог исходных текстов БД и скриптов
FB_SQL\dat      - Каталог скриптов наполнения БД
FB_SQL\res      - Каталог резутатов выполнения SQL-скриптов
FB_SQL\udf      - в каталоге находится файл az-udf.dll, который необходимо
                  скопировать в каталог Firebird\udf. В этой udf содержаться
                  несколько функций необходимых для работы отдельных примеров.
Soft          - В каталоге находится Firebird 2.0 для Windows32, а также 
                демо-версии компонентов для работы с Firebird
Example00IBO    - Использование IBO_TreeView
Example01       - Отображение таблицы People в виде дерева (IBX)
Example01IBO    - Отображение таблицы People в виде дерева (IBO)
Example02       - Отображение таблицы People со структурой Data
Example03       - Справочник по единицам измерения (IBX)
Example03IBO    - Справочник по единицам измерения (IBO)
Example04       - Отображение таблицы Persons
Example05       - Отображение таблицы Goods (1 вариант)
Example06       - Отображение таблицы GoodsNew (2 вариант)
Example07       - Программа подготовки комплексов VAZKompl (упрощенный вар.)
Example07IBORz  - Программа подготовки комплексов VAZKompl (коммерческий вар.)
Example08       - Расчет трудоемкости ремонта АМТС (упрощенный вар.)
Example08IBORz  - Расчет трудоемкости ремонта АМТС (коммерческий вар.)
Example09       - Маленькая бухгалтерская программа
Example10       - Поиск маршрута между двумя станциями метро (на IBX)
Example10IBO    - Поиск маршрута между двумя станциями метро (на IBO)
Example11       - Поиск кратчайшего маршрута между двумя станциями метро
Example12       - Построение таблицы товаров (GoodsNew2) на двух таблицах

Все примеры (за исключением каталога "Soft") можно скачать здесь - размер 28Mb

© 01.08.2009, Архангельский А.Г.

<<Пред. Оглавление
Об Авторе
Все персоны
Главная страница
След.>>



Поддержите культуру
ЯндексЯндекс. ДеньгиХочу такую же кнопку

Google
 
Web azdesign.ru az-libr.ru


Дата последнего изменения:
Wednesday, 23-Oct-2013 09:02:56 UTC