Объектно-реляционная БД Ultima-S

ПРЕДУПРЕЖДЕНИЕ. Автор не несет отвественности за любой ущерб от применения информации из данной работы. Данная публикация не является описанием рабочей спецификации, а только ее урощением. Если вам нужен полноценный вариант обратитесь за консультациями к разработчикам

Организация модели хранения объектов 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