Перечень статей   Терминология   Choose language


Введение в
Tree Manipulation Language


Внешний ключ порождает дерево

Поля двух таблиц связаны внешним ключом (foreign key), а заполняя базу данных, пользователь заносит в связанные поля одинаковые значения. Таким образом нет нужды указывать эти связи в запросе. Такое удобство открывает возможность построения древовидного запроса вида

tablename1.tablename2.tablename3.tablename4
tablename1.*
Не имеет значения, является ли следующее звено дерева родительской таблицей или дочерней - нужна только связь двух таблиц.

Сначала родительская таблица, затем дочерняя

Пусть предшествующим звеном дерева является родительская таблица (таблица "a"), а последующим - дочерняя (таблица "b"), ссылающаяся на первичный ключ родительской. Пусть в дочерней таблице существует несколько записей, ссылающихся на одну и ту же родительскую запись - это означает, что следующий уровень дерева содержит несколько элементов. Звено дерева, состоящее из нескольких записей дочерней таблицы, будем называть множеством (set). Для извлечения дерева перечисляем имена таблиц - сначала родительской, затем дочерней.

DDL TML вывод из СУБД
create table a (
  id   num      primary key,
  data float
);
create table b (
  id   num      primary key,
  ref  num      references a(id),
  data float
);
create table c (
  id   num      primary key,
  link num      references b(id),
  data float
);
insert into a values (1,     12.3);
insert into b values (10, 1, 23.4);
insert into b values (20, 1, 34.5);
insert into b values (30, 1, 45.6);
insert into c values (100,10,56.7);
insert into c values (101,10,67.8);
insert into c values (200,20,78.9);
insert into c values (201,20,89.1);
insert into c values (300,30,91.2);
a.b.c
<a     id=1   data=12.3>
  <b   id=10  data=23.4>
    <c id=100 data=56.7/>
    <c id=101 data=67.8/>
  </b>
  <b   id=20  data=34.5>
    <c id=200 data=78.9/>
    <c id=201 data=89.1/>
  </b>
  <b   id=30  data=45.6>
    <c id=200 data=91.2/>
  </b>
</a>
Если дочерняя таблица двумя своими полями ссылается на две разные записи родительской таблицы, то в TML-запросе после названия дочерней таблицы через знак слэш "/" нужно указать название соответствующего поля дочерней таблицы. Такое указание поля в звене будем называть детерминацией звена (determination). Если детерминацию не указать, то извлечены будут все дочерние записи.
DDL TML вывод из СУБД
create table a (
  id   num      primary key,
  data float
);
create table b (
  id   num      primary key,
  ref1 num      references a(id),
  ref2 num      references a(id),
  data float
);
create table c (
  id   num      primary key,
  lnk1 num      references b(id),
  lnk2 num      references b(id),
  data float
);
insert into a values (1,        12.3);
insert into a values (2,        23.4);
insert into b values (10, 1, 2, 34.5);
insert into b values (20, 1, 2, 45.6);
insert into b values (30, 1, 2, 56.7);
insert into b values (40, 1, 2, 67.8);
insert into c values (100,10,20,78.9);
insert into c values (101,10,20,89.1);
insert into c values (200,30,40,91.2);
insert into c values (201,30,40,88.8);
a.b/ref1.c/lnk1
<a     id=1           data=12.3>
  <b   id=10  ref2=2  data=34.5>
    <c id=100 lnk2=20 data=78.9/>
    <c id=101 lnk2=20 data=89.1/>
  </b>
  <b   id=30  ref2=2  data=56.7>
    <c id=200 lnk2=40 data=91.2/>
    <c id=201 lnk2=40 data=88.8/>
  </b>
</a>

Сначала дочерняя таблица, затем родительская

Пусть предшествующим звеном дерева является дочерняя таблица (таблица "a"), а последующим - родительская (таблица "b"). Звено дерева, состоящее из записи родительской таблицы, будем называть эстафета (relay-race). Для извлечения дерева перечисляем имена таблиц - сначала дочерней, затем родительской.

DDL TML вывод из СУБД
create table a (
  id   num      primary key,
  ref  num      references b(id),
  data float
);
create table b (
  id   num      primary key,
  link num      references c(id),
  data float
);
create table c (
  id   num      primary key,
  data float
);
insert into с values (100,    34.5);
insert into b values (10, 100,23.4);
insert into a values (1,  10, 12.3);
a.b.c
<a     id=1   data=12.3>
  <b   id=10  data=23.4>
    <c id=100 data=34.5/>
  </b>
</a>
Если дочерняя таблица двумя своими полями ссылается на две разные записи родительской таблицы, то в TML-запросе после названия дочерней таблицы через знак слэш "/" нужно указать название соответствующего поля дочерней таблицы. Таким образом таблица и ее ссылающееся поле указываются через слэш в одном звене, а не в разных. Такое указание поля в звене также будем называть детерминацией звена (determination). Если детерминацию не указать, то извлечены будут все родительские записи.
DDL TML вывод из СУБД
create table a (
  id   num      primary key,
  ref1 num      references b(id),
  ref2 num      references b(id),
  data float
);
create table b (
  id   num      primary key,
  lnk1 num      references c(id),
  lnk2 num      references c(id),
  data float
);
create table c (
  id   num      primary key,
  data float
);
insert into с values (201,        78.9);
insert into с values (200,        67.8);
insert into с values (101,        56.7);
insert into с values (100,        45.6);
insert into b values (20, 200,201,34.5);
insert into b values (10, 100,101,23.4);
insert into a values (1,  10, 20, 12.3);
a/ref1.b/lnk1.c
<a     id=1   data=12.3>
  <b   id=10  data=23.4>
    <c id=100 data=45.6/>
  </b>
</a>

Медвежье ухо

Медвежье ухо - это внешний ключ, ссылающийся на первичный ключ этой же самой таблицы. Несколько подряд идущих эстафет, порожденных медвежьим ухом, всегда будем рассматривать как одно звено, и будем называть такое звено списком (list).

По выходным данным (в xml-виде) невозможно определить, было ли звено в базе данных множеством или списком.

create table a (
  id   num      primary key,
  ref  num      references a(id),
  data float
);

Внешний ключ из нескольких полей

Если детерминация не используется, то внешний ключ из нескольких полей не вносит ничего нового. При использовании детерминации все ссылающиеся поля внешнего ключа должны быть перечислены через знак умножения, например как в примере ниже.

a.b/b1*b2*b3.c

Агрегаты

Деревянная модель данных (поверх реляционной) будет иметь своим следствием еще и то, что агрегаты у нее тоже будут деревянные: на любом уровне иерархии дерева, в любом количестве мест могут находится временные переменные, в которых будут накапливаться значения агрегата. А значит располагать временные переменные нужно не в агрегате (как в SQL), а в самой модели данных. Такие "временные" поля реально не существуют, и мы будем помечать их как "fictional" (но они доступны для записи, в отличие от полей с пометкой 'secondary'). Таким образом TML незначительно затрагивает DDL.

create table a {
  a1 int,
  a2 int fictional,
  ...
}

Ввод-вывод данных

Как вывод, так и ввод данных наиболее естественен в виде XML-текста, ибо он доступен человеку для непосредственного восприятия и редактирования (в отличие от бинарных форматов). Для целей ввода и вывода будем полагать, что слова "запись" (из СУБД) и "тег" (из XML) являются синонимами, а также что слова "поле" и "атрибут" также являются синонимами. Например, совершенно законны выражения "вложенная запись" и "вложенная таблица".

Номер TCP-порта, на котором сидит СУБД, и вид протокола связи желательно выбирать таким образом, чтобы хотя бы один из возможных клиентов СУБД мог общаться с нею без промежуточного ПО (без middle-ware). Из всех протоколов (http, ftp, smtp, pop3 и т.д.) наиболее употребительным является HTTP как используемый браузером, поэтому именно через него и будет принимать и отправлять xml-данные ТML4. Значением поля может быть картинка, но по TML-запросу как значение поля отправляется не она, а ее URL для отдельного HTTP-запроса браузера.

Пользователь может отправлять в удаленную или локальную базу данных из командной строки ОС (HTTP спросит логин).

c:/dir>  xml2http.exe remote.database.com username password a.xml

c:/dir>  xml2http.exe 127.0.0.1           username password a.xml
База данных может отправлять в другую удаленную базу данных из триггера или таймера (XML позволяет легко конвертировать данные из одной СУБД в другую; если поля username и password таблицы
sys равны null, то база данных отправляет как 'anonymous')
sql>     update sys set
           ral="database.remote.com",
           username="tomson",
           password="my_pwd";
sql>     a.b.c ;
sql>     update sys set
           ran="101.102.103.104",
           username="tomson",
           password="my_pwd";
sql>     a.b.c ;

Программа-терминал

Все, что посылает триггер или таймер, пользователь может послать из коммандной строки программы-терминала: для Oracle это 'SqlPlus.exe', для Postgres это 'PgSql.exe', для InterBase это 'iSql.exe' и т.д. В каждой начавшейся транзакции (после соединения с базой данных или после команд 'commit' или 'rollback') поля 'ran' и 'ral' таблицы 'sys' всегда указывает на местонахождение самой программы-терминала, поэтому команда

sql>     a.b.c ;
будучи поданной первой после соединения, вернет данные самой программе-терминалу. В зависимости от настроек, программа-терминал может:

Перемежаемость DML- и TML-кода

DML- и TML-коды и данные могут перемежаться: если выражение начинается

Например

CREATE view x as select name, sum(salary) from employee group by name;
x ;

Резюме

Таким образом отличительными особенностями Tree Manipulation Language являются:



Тюрин Дмитрий



Перечень статей   Терминология   Choose language


Сайт управляется системой uCoz