ПРЕДУПРЕЖДЕНИЕ. Автор не несет отвественности за любой ущерб от применения информации из данной работы. Данная публикация не является описанием рабочей спецификации, а только ее урощением. Если вам нужен полноценный вариант обратитесь за консультациями к разработчикам
Организация модели хранения объектов Ultima-S не является полностью оригинальной, а даже скорее классической, на наш взгляд это хороший пример использования гиперключа, дерева и сети объектов.
Организация хранения объектов в системе Ultima-S базируется на концепции главной таблицы с гиперключом. Приведем скрипт данной таблицы с описанием
CREATE TABLE dbo.Docs (
UDN int IDENTITY (1, 1) NOT NULL, --Гиперключ
No varchar (128) NOT NULL , -- Пояснительное поле объекта (чаще его номер в виде строки)
Name varchar (128) NOT NULL , -- Название объекта
Date datetime NOT NULL , -- Дата объекта
Folder int NOT NULL , -- Ссылка на папку вхождения объектов
timestamp timestamp NOT NULL , -- "Штамп" работы с объектом, служит для блокировок
DocFlags smallint NOT NULL , -- Флажки объекта
ParentDoc int NULL , -- Для шорткатов указатель на истинный объект
Class varchar (24) NOT NULL , -- Класс объекта
Deleted tinyint NOT NULL – Признак логически удаленного объекта
)
UDN - это гиперключ, т.е. в базе существует только один данный ключ для всех объектов. Данный ключ суррогатный и представляет собой сквозную нумерацию объектов, имеет смысл кода аналитического учета. UDN никогда не меняется, т.е. каскадных обновлений ключей в БД нет, также чаще всего нет составных ключей. Все это обеспечивает высокую производительность БД. Указанный подход к формированию гиперключа не является единственным и самым удачным, расширенный вариант может всключать в состав гиперключа ID домена и вторичный ключ для целей распределенной БД.
No – поле без фиксированного назначения, чаще всего в него помещают проблемный ключ. В данном случае нумерация объектов и отслеживание ее идентичности ложится на объекты-нумераторы. Заметим, для идентификации объекта нумератор не нужен, он идентифицируется независимо от No по полю UDN
Folder – это ссылка на папку хранения объекта, т.е. Folder содержит UDN объекта-папки. Таким образом, Docs может описывать древовидную структуру. Отдельные ветки данного глобального дерева играют роль древовидных справочников типа "Товары", "Клиенты" и т.д.
Приведем пример алгоритма собирающего все объекты из одной ветки дерева.
delete FolderGroup where TheFolder=@Folder and u=@@spid
insert into FolderGroup(u,TheFolder, UDN, fl) select @@spid, @Folder, @Folder, 1
while (select count(*) from FolderGroup where TheFolder=@Folder and fl=1)>0 begin
insert into FolderGroup (u,TheFolder, UDN, fl)
select @@spid,@Folder, UDN,2 from Docs where Deleted=0 and Folder in (select UDN from FolderGroup where TheFolder=@Folder and fl=1 and u=@@spid)
update FolderGroup set fl=fl-1 where TheFolder=@Folder and fl>0 and u=@@spid
end
ParentDoc – указатель на истинный объект для объекта шорткат (shortcut). Каждый объект может иметь одно физическое нахождение в дереве и множество шорткатов (ссылок) на него. Таким образом, реализуется сетевидное преставление, если в нем есть необходимость.
Рассмотрим пример алгоритма работающего с ParentDoc, точнее дополним алгоритм сбора объектов ветки дерева заменой шорткатов на истинные объекты.
update FolderGroup
set UDN=(select ParentDoc from Docs where UDN=FolderGroup.UDN)
where u=@@spid and (select DocFlags from Docs where UDN=FolderGroup.UDN)=1
and TheFolder=@Folder
Class – название класса объекта
Deleted – указание на логическую удаленность объекта. Чаще всего объекты не удаляются физически, а метятся как удаленные и попадают в архив. Всегда можно восстановить ошибочно удаленный объект.
Таблица Docs позволяет хранить информацию о базовом классе 'Doc', производные классы хранят информацию в дополнительных таблицах, связка осуществляется через UDN.
Например, абстрактный класс "Платежный документ".
CREATE TABLE dbo.PaymentExt (
UDN int NOT NULL , -- Ссылка на гиперключ
VAT money NOT NULL , -- НДС
TSum money NOT NULL , -- Сумма в учетной валюте
PCur int NOT NULL , -- UDN для валюты документа
Stat tinyint NOT NULL , -- Состояние документа
PType tinyint NOT NULL , -- Тип платежа (белый, черный, черно-белый).
Supp int NOT NULL , -- Абстрактный источник
Rec int NOT NULL , -- Абстрактный приемник
SuppPC int NOT NULL , -- Абстрактный центр платежа источника
RecPC int NOT NULL , -- Абстрактный центр платежа приемника
Sum$ money NOT NULL -- Сумма в валюте
)
Как уже отмечалось. Описанный подход к построению ОО БД проверен практикой многих разработчиков. В частности Igor Prokofyev [andrey@ss.relc.com] приводит цитату из документации:
"При работе системы для хранения свойств узлов, узлов, связей между узлами используется реляционная БД. При работе системы в БД сохраняются узлы системы, взаимосвязи между узлами, свойства узлов. В нужный момент времени любой узел системы может быть полно-стью восстановлен из данных БД. Для хранения узлов системы используется таблица zNode. Поле Code хранит код узла; поле Name хранит имя узла; поле Type хранит тип узла. Для хранения связей между узлами системы используется таблица zBond. Поле Code хранит код связи; Поле FromNode хранит код родительского узла; Поле ToNode хранит код подчиненого узла; Поле Fnumber хранит порядковый номер листа в узле."
Vladimir Ivanov. System analyst