Класс-реляционный подход к представлению табличных и XML данных

Сергей Савушкин, 2008

Статья ориентирована на всех, кто интересуется XML базами данных и их возможностями представить реляционные табличные данные. Автор, основываясь на продолжительном опыте разработки системы базы данных (Sav Zigzag ORDBMS), предлагает новые идеи рассматривающие таблицы и XML как формы для представления одной общей модели данных. Идеи позволяют преобразовать набор таблиц в XML без использования отображающих схем. Для навигации через соответствующие табличные данные может быть использован язык XPath.

I. Главные Черты

Введение

Нет необходимости доказывать или упоминать доминирующую роль, которую Реляционные СУБД имеют сейчас. Причина этого, высокая эффективность в обработке данных, которые имеют популярное и простое представление в виде таблиц. Компьютерная поддержка базируется на формализации табличной обработки данных посредством реляционной алгебры, основанной на алгебре множеств. SQL всего лишь естественный язык представления или отображения этой алгебры. Производительность и формализуемость посредством теории множеств предусматривают существенную особенность базы данных, возможность работать с огромными структурированными массивами данных.

Новые системы баз данных, объектно-реляционные СУБД (ОРСУБД), не смогли получить аналогичную популярность. Судьба Informix - существенное подтверждение сказанному. Даже известные ОРСУБД PostgreSQL и Oracle имеют не больше популярности чем MySQL и Microsoft SQL Server, обычно рассматриваемые как РСУБД. Фактически, объектно-ориентированные особенности могут быть легко добавлены любой РСУБД (часто называемой SQL-СУБД). Природа и ядро таких ОРСУБД остается тем же самым (как в РСУБД), также как язык SQL, отражающий табличную модель данных.

В настоящее время мы можем видеть в принципе новый подход к представлению данных в XML-СУБД. Другая иерархическая XML-структура данных основана на других запросных языках XQuery и XPath. XML данные, структура и обработка могут быть формализованы посредством теории множеств и соответствующей алгебры, например XML Query Algebra. Многие сервера/системы претендуют быть высоко-производительными СУБД, например Oracle Berkeley DB XML, Tamino XML Server, MarkLogic Server, eXist Database, Sedna XML DBMS.

XML-СУБД соответствуют упомянутым выше требованиям: высокая производительность и формализация посредством алгебры множеств. Таким образом они могут работать с большой массой данных, что является главной определяющей особенностью СУБД. Свободная ниша, представление Веб-сайтов, кажется с большой вероятностью будет принадлежать XML-СУБД, не РСУБД. А что на счет других ниш, уже занятых РСУБД? Ответить на вопрос достаточно сложно. Главная причина, XML прежде всего был предназначен заменить HTML и представлять иерархию, а не табличную информацию. Простая таблица в XML-форме выглядит неуклюже. Однако, некоторые интересные особенности XML и прежде всего языки XQuery и XPath могут быть перенесены и на табличное представление данных.

Данная статья рассматривает преимущества XML для представления взаимосвязанных много-табличных данных. Эти преимущества обнаруживаются при определенном "класс-реляционном" подходе, описанном ниже. В этом подходе и XML и таблицы - только формы для представления одних данных. Нормализация и денормализация таблиц или разъединение и соединение XML не изменяют реальные данные и структуру в соответствующей базе данных.

Представление данных

Я рекомендую сначала прочитать эссе XML representation of a relational database, один из типичных ранних подходов к XML-представлению табличных данных. Коротко это может быть выражено в следующей иллюстрации, состоящей из таблицы и соответствующего XML.

Форма 1

R

A

B

C

a

b

c

...

 

 

 

<R>  
  <r>
    <A> a </A>
    <B> b </B>
    <C> c </C>
  </r>
  ...
</R>

Это - очень общее поверхностное отображение табличного отношения в XML, которое передает серьезную погрешность в представлении данных от таблиц к XML. Каким является реальное отношение или зависимость между A, B и C? Например, это может быть A -> B -> C, A -> (B, C), (A, B) -> C, A -> B & C-> A и т.д. Даже если мы предположим, что отношение в таблице нормализованное, зависимость может быть A -> (B, C),  (A, B) -> C или даже отсутствовать (A, B, C) -> NONE. Необходимо, чтобы эти зависимости, как однозначные (функциональные), так и многозначные, были видимыми в XML и таблицах. Речь даже не идет о задании ограничения целостности.

Главное достоинство XML - вложенность тэгов. Это - возможность представить не только зависимость колонок в одной таблице. XML является очень удобным для представления взаимосвязанных данных во множестве таблиц. Денормализованное отношение может быть более осязаемым или осмысленным в XML виде, а не в виде таблицы. Мы должны согласиться только, что в случае таких зависимостей как (A, B, ...) -> ANY, для сочетания (A, B, ...) необходимо генерировать суррогатный первичный ключ или использовать естественный, который должен быть представлен в отдельной первой колонке таблицы. То есть первичный ключ должен существовать для любого осмысленного и используемого сочетания колонок. Например, вместо (FIRST NAME, LAST NAME) -> AGE лучше использовать PERSON -> (FIRST NAME, LAST NAME) & PERSON -> AGE. Подход, описываемый здесь, можно продемонстрировать на следующем соответствии между таблицами и XML.

Форма 2

AS

A

B

a

b1

a

b2

...

 

 

BS

B

C

b1

c1

b2

c2

...

 

 

<data>

  <A>a

    <B>b1</B>

    <B>b2</B>

  </A>

  <B>b1

    <C>c1</C>

  </B>

  <B>b2

    <C>c2</C>

  </B>

  ...

</data>

Здесь очень принципиальный момент. Мы все еще не можем говорить однозначно, что таблицы и XML выражают зависимость A -> B, B -> C или, что тоже самое, A -> B -> C. Например, согласно модели данных XML (The XML Data Model), каждый открывающий тэг B, даже с тем же самым текстом 'b1' в форме 2, обозначает новый уникальный XML-элемент типа B. Подобный случай - для таблиц или реляционной модели данных, РМД, см. например The Relational Data Model. Мы не можем гарантировать, что значения колонок (значения атрибутов) 'b1' в колонках (атрибутах) B различных таблиц (отношений) обозначают один общий элемент. Не очевидно даже, что колонки с одним именем B определены одним общим доменом. Данная статья рассматривает другой подход к представлению данных, который предполагает, что все колонки с тем же самым названием означают один класс, также как все тэги с тем же самым именем в соответствующем XML. Я хотел бы назвать такой подход класс-реляционный. Согласно этому подходу, таблицы и XML в форме 2 однозначно представляют отношение между классами A, B, C с зависимостью A -> B-> C. Заинтересованные читатели могут найти дополнительную информацию о класс-реляционных данных и их обработке в описании уже реализованной СУБД и соответствующего языка Zigzag.

Все табличные колонки с одним именем, как и все XML-элементы одного типа объединяются одним именем и отображают один класс. Таким образом, в форме 2, все колонки "B" и XML-элементы "B", это один класс B. Я полагаю здесь, что значение каждого XML-элемента есть текст, помещенный непосредственно после открывающего тега. Значение поля (колонки) таблицы или элемента XML есть значение соответствующего класса определяемого тем же именем, что поле или XML-элемент. Например, в форме 2, все 'b1' где бы они не встречались обозначают только одно значение одного класса B. Если это кажется удобнее, возможно установить значение XML-элемента через "id" атрибут, например, <A id='a'><B>b</B></A> вместо <A>a<B>b</B></A>. Если пара исходных XML-тэгов не задает значение класса, то это значение будет автоматически сгенерировано в базе данных через уникальный идентификатор. Например, я могу ввести в базу данных такую последовательность <A></A></A>. Тогда, если напечатать соответствующее БД-отношение, выводимое XML-представление может иметь вид примерно такой <A id='1'><A id='2'/></A>.

Давайте проанализируем теперь другую денормализованную или соединенную форму представления данных.

Форма 3

AS

A

B

C

a

b1

c1

a

b2

c2

...

 

 

 

<data>

  <A>a

    <B>b1

      <C>c1</C>

    </B>

    <B>b2

      <C>c2</C>

    </B>

  </A>

  ...

</data>

Как мы можем видеть, реляционная зависимость (функциональная или многозначная) правильно отражена только в XML, не в таблице. Значит, денормальная форма таблицы не является точной для класс-реляционного представления (как и для реляционного). Предлагаемый подход предполагает только нормализованные таблицы, которые представляют отношение с A -> (B, ...) зависимостью, где A - имя первой ключевой колонки. Соответствующий XML имеет структуру <A> <B/> ...</A>. Порядок XML-элементов на одном уровне не существенен, они могут иметь то же самое имя типа, но должны отличаться значением или id. Нет необходимости использовать имена таблиц в XML. Более того, имена таблиц в соответствующем табличном представлении могут быть автоматически получены из ключевой колонки или комбинации колонок для таблицы перекрестных ссылок.

XPath-запросы

Навигация по данным в класс-реляционных таблицах и XML может быть выражена посредством XPath-подобного языка. Интересное и полезное описание XPath можно найти в работе XPath 2.0 Expression Syntax Майкла Х. Кей. Я хотел бы сравнить XPath-запросы для одних и тех же данных в реляционном и класс-реляционном представлении. Сначала, я покажу SQL-запрос с тем же самым смыслом, выбирающий все значения C, связанные с A='a' через B. Формы 4, 5, и 6 имеют одну семантику.

Форма 4, Реляционная таблица и SQL

AS

A

B

a

b1

a

b2

 

BS

B

C

b1

c1

b2

c2

 

select BS.C from AS,BS where AS.A='a' and AS.B=BS.B

 

Форма 5, Реляционный XML и XPath/XQuery

<AS>
  <row>
    <A>a</A>
    <B>b1</B>
  </row>
  <row>
    <A>a</A>
    <B>b2</B>
  </row>
</AS>
<BS>
  <row>
    <B>b1</B>
    <C>c1</C>
  </row>
  <row>
    <B>b2</B>
    <C>c2</C>
  </row>
</BS>


XPath:
=/BS/row[B=/AS/row[A='a']/B]/C
XQuery:
for $a in doc("AS.xml")/AS/row[A='a'],
    $b in doc("BS.xml")/BS/row
where $a/B=$b/B
return $b/C

 

Форма 6, Класс-реляционный XML и XPath

<A>a
  <B>b1
    <C>c1</C>
  </B>
  <B>b2
    <C>c2</C>
  </B>
</A>

 
XPath:
=A[.='a']/B/C

Я надеюсь все согласятся, класс-реляционный XPath (Форма 6) выглядит более простым и понятным. Более того, XPath с вложенными квадратными скобками (Форма 5) не работает в современных XPath реализациях. Для реляционного XML-представления такой запрос задается в XQuery.

Класс-реляционные XML и XPath работают с отношением между значениями классов, а не с таблицами (наборами рядов). Чтобы получить значения C имеющие отношение с A='a', я мог бы использовать даже такое выражение A[.='a']//C. Конструкции с начальным символом слэш, подобные  /A, здесь не требуются. Я хотел бы также отметить важную особенность класс-реляционных данных, которая следует скорее из нормализованного разъединенного XML или таблиц. Каждый класс может быть доступным непосредственно. Мы можем получить все значения C просто посредством C/. или C[.] без навигации через A и B. Другие простые запросы, например выборка значений A связанных с C='c1' выглядели бы таким образом:
=A[./*/C='c1']
=A[.//C='c1']
=A[B[C[.='c1']]]
=A[B[C='c1']]
=A[*[C='c1']]

II. Реляционный Пример

От таблиц к XML

Давайте рассмотрим почти типичный пример реляционной базы данных.

Форма 7

DEPARTAMENTS

DEPARTMENT_ID

NAME

BRANCH

D1

SoftS

IT

D2

HardS

IT

WORKERS

WORKER_ID

NAME

DEPARTMENT_ID

W1

Fisher

D1

W1

Fisher

D2

W2

Smit

D1

W3

Smit

D2

Две таблицы связаны друг с другом через колонку DEPARTMENT_ID. Тип этой взаимосвязи - агрегация, где DEPARTMENTS имеют WORKERS. Мы рассматриваем агрегацию N:M, потому что один рабочий Fisher (как исключение) работает в нескольких отделах. DEPARTMENT_ID - внешний ключ в таблице WORKERS. Первые колонки в обеих таблицах - ключевые.

Ниже то же самое отношение в денормализованной табличной и XML формах:

Форма 8

data

BRANCH

DEPARTMENT_ID

NAME

WORKER_ID

NAME

IT

D1

SoftS

W1

Fisher

IT

D1

SoftS

W2

Smit

IT

D2

HardS

W1

Fisher

IT

D2

HardS

W3

Smit

 

<data>

  <BRANCH>

    IT

    <DEPARTMENT id='D1'>

      <NAME>

        SoftS

      </NAME>

      <WORKER id='W1'>

        <NAME>

          Fisher

        </NAME>

      </WORKER>

      <WORKER id='W2'>

        <NAME>

          Smit

        </NAME>

      </WORKER>

    </DEPARTMENT>

    <DEPARTMENT id='D2'>

      <NAME>

        HardS

      </NAME>

      <WORKER id='W1'>

        <NAME>

          Fisher

        </NAME>

      </WORKER>

      <WORKER ID='W3'>

        <NAME>

          Smit

        </NAME>

      </WORKER>

    </DEPARTMENT>

  </BRANCH>

</data>

От XML к таблицам

Я уже отмечал ранее, что XML и таблицы - только форма представления данных хранимых внутри базы данных. Те же самые данные должны легко преобразовываться из одной формы в другую. Однако, для наследуемых систем с существующим XML или табличными приложениями, весьма желательным была бы отображающая схема, регулирующая соответствие между XML и таблицами. Чтобы преобразовать класс-реляционные данные из XML в наиболее соответствующее табличное представление (4-ая нормальная форма), я преобразую XML в форме 8 в другое разъединенное представление. Только затем, я получу соответствующее класс-реляционное множество таблиц.

Форма 9

<data>

  <BRANCH>

    IT

    <DEPARTMENT id='D1'>

    <DEPARTMENT id='D2'>

  </BRANCH>

 

  <DEPARTMENT id='D1'>

    <NAME>

      SoftS

    </NAME>

    <WORKER id='W1'/>

    <WORKER id='W2'/>

  </DEPARTMENT>

  <DEPARTMENT id='D2'>

    <NAME>

      HardS

    </NAME>

    <WORKER id='W1'/>

    <WORKER ID='W3'/>

  </DEPARTMENT>

 

  <WORKER id='W1'>

    <NAME>

      Fisher

    </NAME>

  </WORKER>

  <WORKER id='W2'>

    <NAME>

      Smit

    </NAME>

  </WORKER>

  <WORKER ID='W3'>

    <NAME>

      Smit

    </NAME>

  </WORKER>

</data>

 

BRANCHES-DEPARTAMENTS

BRANCH

DEPARTMENT_ID

IT

D1

IT

D2

 

DEPARTAMENTS

DEPARTMENT_ID

NAME

D1

SoftS

D2

HardS

 

DEPARTAMENTS-WORKERS

DEPARTMENT_ID

WORKER_ID

D1

W1

D1

W2

D2

W1

D2

W3

 

WORKERS

WORKER_ID

NAME

W1

Fisher

W2

Smit

W3

Smit

Самое компактное и желательное представление отношения в базе данных - нормальная табличная или разъединенная XML форма. Таблицы могут иметь и любой другой вид, но с обязательным отдельным описанием зависимостей между их колонками. Соединенная XML форма может быть подходящей в основном для представления полной связанной иерархии, например для иллюстрации выполнения запросов. В случае манипуляции данных, лучше рассматривать разъединенную XML-форму или соответствующую нормальную табличную форму. Я говорю о специфике представления класс-реляционных данных при навигации и контроле за целостностью.

Целостность данных

Последняя форма 9 показывает пример класс-реляционной зависимости. Модель данных рассматриваемых класс-реляционных таблиц и XML не коррелирует с моделями реляционых таблиц и естественного (native) XML. Мы можем видеть DEPARTEMENT с ID ='D1' в нескольких таблицах, но это - однозначно тот же самый элемент. В нашем случае DEPARTMENT с ID=’D1’ связан также со значением NAME = 'SoftS' и со значениями WORKER_ID = ('W1', 'W2'). Давайте попробуем удалить DEPARTEMENT_ID = 'D1'. Уникальное значение NAME = 'SoftS' (поле и тэг) будет удалено также. Главная причина, потому что NAME = 'SoftS' теряет все связи (отношение) с другими значениями. Нет смысла хранить это имя. Кроме того, это зависимое значение. Удаление BRANCH='IT' не подразумевает удаление связанных DEPARTEMENTs, потому что они имеют другую связь с другими элементами. (Считаете, что пример неудачен? Хорошо, давайте предполагать, что эти отделы будут принадлежать в будущем другому филиалу. То есть, информация о них должна быть сохранена).

Определение типа значений класса не так необходимо для класс-реляционных данных, хотя очень желательно. Мы можем определить схему базы данных отдельно даже для уже существующих данных, что допустимо в XML-базах данных. Я сознательно использовал в предыдущем примере один класс NAME, связанный с классами DEPARTEMENT и WORKER. Класс NAME есть общий класс. Лучше (но необязательно) его разделить на другие классы, такие как WORKER_NAME и DEPARTEMENT_NAME с разными типами значений. Тем не менее, если позволяет реализация, типы (домены) значений класса могут быть определены также в зависимости от их отношения с другими классами. Например, классы NAME(WORKER) и NAME(DEPARTEMENT), или в XPath нотации WORKER / NAME и DEPARTEMENT / NAME, вполне могут иметь разные типы.

Заключение

Данная работа демонстрирует некоторые особенности и возможности разработанной и реализованной системы базы данных, имеющей специфичную "класс-реляционную" организацию данных. Соответствующая класс-реляционная база данных рассматривает табличные колонки с одним и тем же именем, как один независимый класс. Это - главное отличие от реляционных (или SQL) баз данных, которые не предполагают строгую ассоциацию между колонками с одинаковым именем в различных таблицах. Таблицы и XML - только формы для представления отношения между значениями класса. То есть одно и то же значение класса может встречаться в разных полях таблиц или тэгах XML, при этом обозначать один и тот же объект для полей или тэгов с одинаковым именем .

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

К сожалению в разных подходах и моделях данных термин класс до сих пор не имеет четкого определения и понимания. Чаще всего его ассоциируют с типом. Так или иначе, тип и класс, это - разные термины и в конечном счете обозначают и должны обозначать разные понятия. Основываясь на объектной модели ODMG под классом можно понимать отображение (например имплементацию) типа на его экстент, то есть на множество экземпляров (instances). Класс, кроме всего прочего, может включать в себя подклассы и образовывать некую иерархию классов, соответствующую иерархии определенных типов.

В описываемом подходе класс, это - множество текущих (хранимых в БД или рассматриваемых в данный момент) значений сгруппированных одним именем. Типом класса является определение множества всех возможных значений данного класса. Иерархия имен задает иерархию классов. Допускается и даже является весьма полезным использование одного имени для класса и соответствующего ему типа, особенно на верхних уровнях иерархии. Только в случае совпадения имен между классом и типом, срабатывает ODMG-подход к определению класса. Что следует понимать под значением? Все что угодно. Важно чтобы оно хранилось внутри БД. Сочетание имени класса и его значения может использоваться, например, в качестве идентификатора объекта.

Данная статья - очередная, подкрепленная практическими результатами, попытка перенести объектность в реляционную модель данных. Специфика и главное противоречие класс-реляционного подхода с существующими моделями заключается в трактовке атрибута. Это сделано не только ради практических целей, упрощения языкового интерфейса и эффективной реализации операций обработки данных, ВЫБОРКИ (ОГРАНИЧЕНИЯ), ЕСТЕСТВЕННОГО СОЕДИНЕНИЯ и ПРОЕКЦИИ в терминах реляционной модели. Имеется и семантическая подоплека, связанная с пониманием естественного языка. Атрибут в данном подходе рассматривается как класс. Любой атрибут обозначающий роль, имя, свойство и т.д. в конечном счете является классом. Речь идет как об отдельном атрибуте, рассматриваемом независимо от других, например ИМЯ, БОЛЬШЕ, РАЗМЕР и т.д., так и об атрибуте связанном отношением, рассматриваемым в контексте с другими атрибутами (классами J), например ИМЯ СОТРУДНИКА, ДВИГАТЕЛЬ БОЛЬШЕГО РАЗМЕРА, ….