Скажу сразу, что описание данных я буду давать в синтаксисе SQLBase. А теперь рассмотрим, как задачи, которые помогает решать Дизайнер повлияли на структуру данных...
И, для начала, пара служебных табличек - списки констант... периодически нужны, используются вообще говоря, всюду. Более подробно о точках применения буду говорить когда нужно, а пока же, просто таблички.
Список числовых констант:
CREATE TABLE SYSADM.CONSTNUMB ( ID VARCHAR(18) NOT NULL, IDENVIR DOUBLE PRECISION, NAMECONST VARCHAR(50), SENSE DOUBLE PRECISION ) /
ID - что тут сказать? Константы нужны, и выбор будет происходить именно по идентификатору. Особенность в том, что эти ID символьные (почему именно, я расскажу чуть позже), а пока же, давайте просто примем - идентификаторы у нас символьные.
IDENVIR - для удобства редактирования (представления) данных для пользователя мы разделили их на разделы по тематическим областям, и сразу, регион под номером "-1" - список системных констант.
NAMECONST - название константы
SENSE - значение
Список строковых констант:
CREATE TABLE SYSADM.CONSTCHAR ( ID VARCHAR(18) NOT NULL, IDENVIR DOUBLE PRECISION, NAMECONST VARCHAR(50), SENSE VARCHAR(253) ) /
И поскольку назначения полей в таблицах совпадают, я их не буду описывать еще раз.
Теперь можно начать разговор о дизайнере. Начинаем со списка заготовок документов: Понятно, что каждый документ должен быть как-то описан... естественно, название, некий "тип"...
CREATE TABLE SYSADM.LISTPATTERN ( ID VARCHAR(18) NOT NULL, DOCNAME VARCHAR(20) NOT NULL, DOCABOUT LONG VARCHAR, IDDOCTYPE VARCHAR(18), IDSOUAPP VARCHAR(18), IDSOUWIZ VARCHAR(18), IDBDAPP VARCHAR(18), IDBDWIZ VARCHAR(18) ) /
ID - каждый документ имеет свой, уникальный Идентификатор.
DOCNAME - название, а как же без названия? :-)
DOCABOUT - описание документа.
IDDOCTYPE - тип документа - Идентификатор строки из таблицы CONSTNUMB.
IDSOUAPP - Идентификатор исходника приложения
IDSOUWIZ - Идентификатор исходника волшебника
IDBDAPP - Идентификатор "экзешника" приложения
IDBDWIZ - Идентификатор "экзешника" волшебника
Все четыре поля - идентификаторы соответствующих строк из таблицы LISTBODY.
Ограничения:
ALTER TABLE SYSADM.LISTPATTERN FOREIGN KEY LIPAT001 ( IDDOCTYPE) REFERENCES SYSADM.CONSTNUMB /
Нам важно, чтобы нельзя было удалить строчки в списке констант, если есть документы соответствующих типов.
ALTER TABLE SYSADM.LISTPATTERN FOREIGN KEY LIPAT002 ( IDSOUAPP ) REFERENCES SYSADM.LISTBODY /
ALTER TABLE SYSADM.LISTPATTERN FOREIGN KEY LIPAT003 ( IDSOUWIZ ) REFERENCES SYSADM.LISTBODY / ALTER TABLE SYSADM.LISTPATTERN FOREIGN KEY LIPAT004 ( IDBDAPP ) REFERENCES SYSADM.LISTBODY / ALTER TABLE SYSADM.LISTPATTERN FOREIGN KEY LIPAT005 ( IDBDWIZ ) REFERENCES SYSADM.LISTBODY /
Да, уважительное отношение с "телам" :-)) - по идее, очень правильно.
Документ, как некая экранная форма, состоит из полей (числовых, символьных и т.д.) и табличек. Данные документа хранятся в базе данных в неких табличках, список полей - в одной, (наверное) каждая из таблиц в другой. Вот их - то и надо определить, создать, и не просто создать, а навесить достаточно много ограничений целостности. Как все это автоматизировать? Почти никак, ну, разве что, можно (и нужно) позволить разработчику придумать структуру таблицы, а вот слово CREATE можно поручить компьютеру, да и вдобавок, структуру таблицы придумали в одном месте, а создать ее надо на сервере, который находится... (очень далеко) вот... И что делать?
Мы подумали и решили, что с документами в этой системе будет связан список подчиненных табличек...
CREATE TABLE SYSADM.LPATTABLES ( ID VARCHAR(18) NOT NULL, IDDOC VARCHAR(18), TABNAME VARCHAR(18) NOT NULL, TABLEABOUT LONG VARCHAR, FLAG CHAR(1), IDTABDERIVE VARCHAR(18) ) /
ID - уникальный Идентификатор описываемой таблицы
IDDOC - Идентификатор документа, хозяина таблицы
TABNAME - имя таблицы
TABLEABOUT - описание таблицы
FLAG - флаг, идентификатор из таблицы
IDTABDERIVE - таблицы документов могут иметь похожую структуру, и, можно сказать, что одну, мы делаем как наследника от другой, и просто добавляем недостающие поля, и в этом поле помещаем уникальный идентификатор конкретной таблицы (из LPATTABLES) это поле работает только при редактировании состава таблицы.
Ограничения:
ALTER TABLE SYSADM.LPATTABLES FOREIGN KEY LIPATTAB001 ( IDDOC) REFERENCES SYSADM.LISTPATTERN /
Нам важно, чтобы было нельзя удалить описание документа, если еще существуют его таблицы.
Всякая таблица в любом SQL-сервере состоит из колонок... значит, нам нужно их описание...
CREATE TABLE SYSADM.LTABCOLUMNS ( IDTAB VARCHAR(18) NOT NULL, NUMORD DOUBLE PRECISION NOT NULL, NAME VARCHAR(20) NOT NULL, TYPECOL VARCHAR(20) NOT NULL, LENGTH DOUBLE PRECISION, "PRECISION" DOUBLE PRECISION, SETIND CHAR(1), OFDELRIVE CHAR(1) ) /
IDTAB - идентификатор родительской таблицы
NUMORD - номер столбца, вообще говоря, ни к чему не обязывает, но, но просто приятно видеть столбцы в правильном порядке....
NAME - понятно, название
TYPECOL - тип данных, выбор из списка данных, с которыми работает сервер... правда, не все так просто - есть еще и наши типы, а вот с ними надо будет разбираться еже при описании "экзешника" - все там...
LENGTH - длина данных ("CHAR", "DECIMAL")
PRECISION - точность, для столбцов типа DECIMAL
SETIND - флажок индексируемости, если мы подозреваем, что нам надо индексировать текущий столбик, то...
OFDELRIVE - это показатель унаследованности :-), если табличка, вернее некоторая часть ее колонок точно такая же как и в некой иной таблице (той, что можно считать предком текущей...)
Ограничения:
ALTER TABLE SYSADM.LTABCOLUMNS FOREIGN KEY LTCOLUMNS001 ( IDTAB ) REFERENCES SYSADM.LPATTABLES /
Нам важно, чтобы было нельзя удалить описание таблицы, если еще существуют ее колонки.
Ну вот, чем дальше в лес, тем толще помидоры... Про репликацию я уже говорил? Да, и про то, что надо иметь возможность каким-то образом создать таблицы, принадлежащие документу, на неком очень удаленном сервере... как? Возможно неким "экзешником", который будет вести процесс реплицирования. И, для работы этого процесса нам нужно подготовить список команд. И вот что получается: Дизайнер, анализирую состав таблиц LPATTABLES и LTABCOLUMNS генерирует набор SQL команд, при исполнении которых открываются необходимые SQL-объекты.
Таблица для хранения списка этих команд:
CREATE TABLE SYSADM.LISTCREATEOBJ ( IDTABLES VARCHAR(18) NOT NULL, NUMORDER INTEGER NOT NULL, TEXT LONG VARCHAR ) /
IDTABLES - Идентификатор таблицы, которой принадлежат команды.
NUMORDER - номер по порядку выполнения команд (известно ведь, что правильнее сначала открыть таблице, а потом открывать ее индексы)
TEXT - собственно, текст команды.
Ограничения:
ALTER TABLE SYSADM.LISTCREATEOBJ FOREIGN KEY LITABLE0621 ( IDTABLES) REFERENCES SYSADM.LPATTABLES /
Нам важно, чтобы было нельзя удалить описание таблицы, если еще существуют ее команды открытия...
Следующий вопрос на повестке дня - отчеты... и, небольшое отступление: Мир не идеален, и поэтому во многих местах еще требуют "бумажки" :-) и, наша система (документы) их, по-идее, должна делать... причем, очень часто получается, что у одного документа должно быть несколько бумажных представлений. Их проще всего назвать "отчетами".
Что еще? Подготовку отчета к печати делает (во-всяком случае в нашей системе) сторонний модуль. Да и разработка внешнего вида тоже чего - то стоит... и этого нужны некие данные... вот их то мы и оформили в таблицу.
CREATE TABLE SYSADM.LISTREP ( ID VARCHAR(18) NOT NULL, IDDOC VARCHAR(18), NAME VARCHAR(20), NAMESELECT VARCHAR(18), STRINTO LONG VARCHAR, STRWHERE LONG VARCHAR, STRITEM LONG VARCHAR, IDBODY VARCHAR(18) ) /
ID - Идентификатор
IDDOC - Идентификатор документа-"хозяина"
NAME - имя отчета
NAMESELECT - название команды выбора данных (из списка хранимых команд)
STRINTO - строка с перечисленными полями "куда"
STRWHERE - строка параметров выбора данных
STRITEM - строка переменных отчета - в полном соответствии со строкой STRINTO
IDBODY - Идентификатор соответствующей строки из таблицы LISTBODY, в одном из столбцов которой находится "тело" отчета
Ограничения:
ALTER TABLE SYSADM.LISTREP FOREIGN KEY LISTREP001 ( IDDOC) REFERENCES SYSADM.LISTPATTERN /
Естественно, не хотелось бы позволить удалить описание документа, если существуют описания отчетов.
ALTER TABLE SYSADM.LISTREP FOREIGN KEY LISTREP002 ( IDBODY) REFERENCES SYSADM.LISTBODY /
Тело отчета... не хотелось бы позволить "шаловливым ручкам" удалить его из базы...
Вот и добрался я до уже несколько раз произносимого названия - LISTBODY. Документ это не только данные, но и "экзешники", "отчеты", а кроме этого есть еще и исходные тексты... что еще? А вдруг для нормальной работы "экзешнику" нужны еще и некие "dll"... И есть необходимость доставить все это хозяйство к пользователю... А ведь мы заранее не знаем, где будет работать некий документ (я имею ввиду географию расположения компьютеров, то ли это соседний кабинет, а может и за тридевять земель) и, мы не представляем, с каким сервером документ будет обмениваться данными, единственное, что точно известно, так то, что все сервера связаны друг с другом, и по неким правилам обмениваются данными. (Репликация же предполагается :-))
Значит, чтобы нам доставить документ к пользователю надо превратить его в данные. Все принадлежащие документу модули - файлы, и их можно просто залить на сервер в месте, где ведется разработка и вынуть там, где это нужно (на компьютере пользователя). Вот как раз для хранения такого рода данных и предназначена таблица:
CREATE TABLE SYSADM.LISTBODY ( ID VARCHAR(18) NOT NULL, IDDOC VARCHAR(18) NOT NULL, NAMEFILE VARCHAR(254), BODY LONG VARCHAR, SIZE DOUBLE PRECISION, BODYDATE TIMESTAMP, FLAG CHAR(1) NOT NULL ) /
ID - Идентификатор
IDDOC - Идентификатор Документа, которому принадлежат "единицы хранения"
NAMEFILE - имя файла, хранимого в строке...
BODY - собственно хранимый объект
SIZE - размер объекта
BODYDATE - дата создания файла, который был залит в базу сделано для сверки версий файлов на клиентской машине и в базе. Если в базе соответствующий файл новее, то его можно перелить на клиентскую машину...
FLAG - "A" - исходник, "E" - "экзешник", "D" - DLL'ка - возможно, когда-нибудь понадобится... "R" - "отчет"
Ограничения:
ALTER TABLE SYSADM.LPATTABLES FOREIGN KEY L001 ( IDDOC) REFERENCES SYSADM.LISTPATTERN /
Не хотелось бы позволить удалить описание документа, если существуют некие объекты, связанные с документом...
Так что, уже добрались до списка документов? :-)) хорошо...
Мы считаем, что все документы, с которыми будет работать система имеют некие общие параметры - в частности, номер, дату, и автора, а кроме того, некие комментарии, сумму и количество. Вот это мы и решили объединить одну таблицу.
CREATE TABLE SYSADM.LISTDOC ( ID VARCHAR(18) NOT NULL, DOCNUM VARCHAR(20), DOCDATE DATE, IDDOC VARCHAR(18), IDUSER VARCHAR(18), STRCOMMENT VARCHAR(128), NCQUERY DECIMAL(15, 3), NCSUMM DECIMAL(15, 3) ) /
ID - Идентификатор данных документа
DOCNUM - номер документа
DOCDATE - дата создание документа
IDDOC - Идентификатор Документа, на самом деле это ТИП документа. (Идентификатор строки, из таблицы LISTPATTERN)
IDUSER - Идентификатор пользователя (из списка пользователей) - об этом я еще много- чего расскажу, но, чуть - попозже...
STRCOMMENT - комментарии...
NCQUERY - иногда про документ хорошо знать некое количество...
NCSUMM - тоже самое можно сказать и про сумму...
Ограничения:
ALTER TABLE SYSADM.LPATTABLES FOREIGN KEY LDOC001 ( IDDOC ) REFERENCES SYSADM.LISTPATTERN /
Поскольку список документов штука типизированная - документы могут быть только предопределенных типов, то было бы не правильно позволить удалить описание документа, если еще есть документы.
ALTER TABLE SYSADM.LPATTABLES FOREIGN KEY LDOC002 ( IDUSER ) REFERENCES SYSADM.LISTUSER /
Аналогично, пользователи - создатели документов, ну не правильно же позволить удалить пользователя, если еще есть документы им созданные...
Интересный вопрос - а как (реально, как) удалить некий документ? - то есть, после создания документа, после полу- годовой работы с ним пользователей :-)) - мы (господа "криэйторы) вдруг обнаружили, что некий документ оказался лишним, и его надо удалить полностью ! Процесс "выкусывания" оказался несколько нетривиальным, и его обсуждение я решил вынести на повестку дня отдельно...
А пока мне осталось только добавить маленький кусочек - набор всех описанных табличек в одном SQL файле, который Вы можете взять из проекта.