Летом 1998 г. в издательстве Addison-Wesley вышла книга Криса Дейта и Хью Дарвена "Foundation for Object/Relational Databases: The Third Manifesto". В этой книге глубоко и обоснованно развиваются идеи, первоначально сформулированные в статье тех же авторов [1]. На мой взгляд, книга содержит ряд спорных утверждений и предположений, но прошедшие со дня ее выхода месяцы показали наличие достаточно активного интереса к книге, и имеются основания полагать, что она повлияет на будущие теорию и практику баз данных.
Поскольку для широкого круга русских читателей книга практически недоступна, я решил в нескольких статьях познакомить вас с основными идеями книги. Это будет не просто пересказ, поскольку по мере возможности я буду комментировать спорные (с моей точки зрения) места. В тексте эти комментарии выделяются курсивом.
Первая статья посвящается вводной главе книги "Предпосылки и обзор", в которой описываются причины, побудившие авторов к ее написанию, и приводится краткий обзор базовых идей, а также второй главе "Объекты и отношения", где обсуждаются связь понятий "объект" и "отношение".
Причины написания книги
Указываемой первичной причиной является неудовлетворенность предлагаемыми другими исследователями и авторами подходами к интеграции реляционной и объектной технологии. Публикации [1] предшествовали два манифеста - Манифест объектно-ориентированных систем баз данных [2] и Манифест систем баз данных третьего поколения [3], в каждом из которых предлагался некоторый базис для развития будущих СУБД. Но при этом:
Это первое спорное утверждение. Как известно, объектно-ориентированные и другие нереляционные СУБД достаточно успешно существуют и используются.
В отличие от этого, Д&Д категорически утверждают, что в интересах будущего развития требуется полностью отказаться от SQL. Осознавая наличие громадного числа SQL-ориентированных баз данных и приложений, которые будут продолжать использоваться в течение долгого времени, Д&Д соглашаются с тем, что требуется уделять некоторое внимание продолжению поддержки наследства SQL.
Назад к реляционному будущему
Основным тезисом книги является то, что мы должны отказаться от SQL и вернуться к реляционным истокам. Д&Д считают, что необходимую основу обеспечивает Реляционная Модель Данных, впервые представленная миру Эдвардом Коддом в 1969 г. Признавая желательность объектно-ориентированных свойств в системах баз данных, Д&Д полагают, что эти свойства являются ортогональными к реляционной модели. Не требуются какие-либо переделки реляционной модели, чтобы можно было определить язык, который
Если предположить существование такого языка D (а позже в книге приводится неформальное описание языка Tutorial D), то, по мнению Д&Д, он должен соответствовать ряду положительных и отрицательных утверждений (prescriptions и proscriptions). Авторы выделяют утверждения, происходящие из реляционной модели (RM Prescriptions), и те, которые к ней не относятся, - Other Orthogonal (OO) Prescriptions.
Обратите внимание, что везде далее в книге OO используется именно в смысле Other Orthogonal, а не Object-Oriented, хотя, конечно, в основном имеются в виду объектные свойства.
При этом утверждения категории RM считаются необсуждаемыми, но что касается OO-утверждений, то отсутствие общепризнанной модели делает их в некотором роде "пробными". Кроме того, в книге содержится набор Весьма Строгих Утверждений, которые тоже разбиты на категории RM и OO.
Некоторые руководящие принципы
Во всей своей книге Д&Д следуют некоторым руководящим принципам, среди которых основным и определяющим является максима, принадлежащая, как думают авторы, Людвигу Витгенштейну:
ВСЕ ЛОГИЧЕСКИЕ РАЗЛИЧИЯ ЯВЛЯЮТСЯ БОЛЬШИМИ РАЗЛИЧИЯМИ
Это особенно важно к контексте реляционной модели, являющейся формальной системой, а основой любой формальной системы является логика.
Следствием этой максимы является тот принцип, что логические ошибки являются большими ошибками. В индустрии баз данных делалось и делается большое число таких ошибок.
Д&Д считают верным принцип, основанный на противоположном толковании максимы Витгенштейна: все различия, не являющиеся логическими, представляют собой небольшие различия. Одним из результатов следования этому принципу является то, что при определении Tutorial D Д&Д обращали больше внимания на логичность построения языка, а не на его синтаксис.
Наконец, еще один фундаментальный принцип, которому очень трудно следовать, почерпнут из Мифического человекомесяца Фреда Брукса - это принцип концептуальной целостности.
Некоторые решающие логические различия
Модель и реализация
В книге главным образом обсуждаются аспекты модели, а не реализации. Кроме того, под реализацией понимается реализация "системы" (т.е. СУБД), а не некоторого приложения, работающего под управлением этой системы.
Думаю, что с таким определением модели не согласятся математики, хотя на интуитивном уровне оно правильно. Вообще говоря, поскольку модель - это формальная система, ее определение тоже должно быть формальным.
Значения и переменные
Люди часто путают эти простые и фундаментальные понятия. В соответствии с Кливлэндом в книге используются следующие определения:
Значения могут быть произвольно сложными; например, значение может быть массивом, стеком, списком, геометрической точкой, документом и т.д. Аналогичные замечания относятся и к переменным.
Как отмечают Д&Д, большая путаница по поводу значений и переменных имеется в объектном мире, где различают тип переменной и тип объекта, являющегося текущим значением этой переменной; объекты и значения; признают наличие операций, воздействующих на состояние объекта. Именно по причине этой путаницы авторы книги стараются вообще не использовать термин "объект".
Значения, кодировки и появления
Логическое различие проводится между значением как таковым и кодировкой этого значения, появляющимися в некотором конкретном контексте. Одно и то же значение, или, вернее, кодировки одного и того же значения могут одновременно появляться в нескольких разных контекстах, и сами эти кодировки не обязательно все одинаковы. Например, целое значение "3" является единственным во множестве целых чисел, но произвольное число переменных может содержать некоторую кодировку этого целого числа как свое текущее значение. Некоторые из этих переменных могут содержать десятичную кодировку этого целого числа, а другие, например, двоичную. Следовательно, имеется логическое различие между кодировкой значения и появлением этой кодировки в некотором контексте, а также между кодировками, появляющимися в разных контекстах.
Умышленно опущенные темы
Имеется много практически необходимых аспектов систем управления данными, которые не имеют отношения к логической основе таких систем. К этим аспектам, в частности, относится следующее:
Книга не ориентирована на обсуждение подобных аспектов.
Сводка утверждений и очень строгих суждений
Положительные RM-утверждения
Отрицательные RM-утверждения
Положительные OO-утверждения
Отрицательные OO-утверждения
Очень строгие RM-суждения
Очень строгие OO-суждения
Введение
Чтобы иметь возможность достаточно детально обсудить вопрос интеграции объектов и отношений, необходимо понять, какая концепция в реляционном мире является двойником концепции класса объектов в объектном мире. Этот вопрос имеет определяющее значение, поскольку именно класс объектов является фундаментальной концепцией объектного мира, и все остальные объектные понятия в большей или меньшей степени зависят от этой концепции.
Можно предложить два возможных ответа на поставленный вопрос:
В главе показывается, что первый ответ - правильный, а второй - нет.
Что за проблему мы пытаемся решить?
Исходным положением является то, что для будущих баз данных потребуются гораздо более сложные виды данных, чем те, которые поддерживаются в современных коммерческих базах данных. Возникает потребность хранить графические данные, аудио- и видеоданные и т.д. Каким образом можно поддерживать новые виды данных, оставаясь в классической реляционной среде? Д&Д принимают как аксиому то, что мы хотим остаться в классической реляционной среде; было бы неразумно забыть о результатах многолетних исследований и разработок в этой области.
Отношения и relvars
Прежде всего необходимо устранить недоразумение, существующее с начала реляционной эры. Рассмотрим отношение MMQ, показанное на рис. 1:
MMQ | MAJOR_P# : P# | MINOR_P# : P# | QTY : QTY |
P1 | P2 | 5 | |
P1 | P3 | 3 | |
P2 | P3 | 2 | |
P2 | P4 | 7 | |
P3 | P5 | 4 | |
P4 | P6 | 8 |
Рис. 1. Отношение инвентарной ведомости MMQ
Как видно, каждое отношение состоит из двух частей - заголовка и тела, где заголовок - это множество пар имя-столбца:имя-домена, а тело - множество строк, соответствующих этому заголовку. Для отношения MMQ:
Замечание Д&Д: Из соображений точности изложения в книге используется термин "отношение", а не термин "таблица", и термины "атрибут" и "кортеж", а не "столбец" и "строка". Исключения из этого правила допускаются только в тех случаях, где точность необязательна.
Как видно из дальнейшего изложения эти исключения встречаются чрезвычайно часто.
Вот важный способ понимания природы отношений (хотя, возможно, необычный). Для заданного отношения R заголовок R задает предикат (истинностную функцию), а каждая строка тела R - это истинное высказывание, получаемое из предиката путем подстановки некоторых значений доменов вместо параметров этого предиката. Например, для отношения MMQ предикат мог бы выглядеть следующим образом:
part MAJOR_P# contains QTY of part MINOR_P#
(деталь MAJOR_P# содержит QTY деталей MINOR_P#)
Соответствующими истинными высказываниями являются следующие:
part P1 contains 5 of part P2
(деталь P1 содержит 5 деталей P2);
part P1 contains 3 of part P3
(деталь P1 содержит 3 детали P3) и т.д.
Коротко говоря,
Поэтому
Хорошей, хотя и не вполне строгой аналогией является то, что домены для отношений - то же самое, что существительные для предложений.
Вернемся теперь к исторически существующей путанице между значениями отношений и переменными отношений. Если мы говорим на некотором языке программирования
DECLARE N INTEGER … ;
то N - это не целое число, это целая переменная, значениями которой являются целые числа. Точно так же, когда мы говорим на языке SQL
CREATE TABLE R … ;
то R - это не отношение, а переменная отношения, значениями которой являются отношения. Когда мы обновляем R (например, вставляем строку), то на самом деле заменяем старое значение-отношение R на новое, другое значение-отношение.
Трудность в том, что когда люди говорят об отношениях, они очень часто имеют в виду переменные отношений. Однако здесь имеется логическое различие, т.е. большое различие. Например, значение данного отношения (множество строк) не меняется во времени, в то время, как значение переменной данного отношения, конечно, меняется. Подобно отношению и в отличие от переменной отношения значение данного домена (множество скаляров) также не меняется во времени, и поэтому некоторые люди полагают, что домены и отношения имеют одну и ту же природу. И, наконец, введенные в заблуждение смешением понятий отношений и переменных отношений, некоторые люди еще больше заблуждаются, считая, что у переменных доменов и переменных отношений одна и та же природа.
Стремясь внести в эти вопросы максимальную ясность, Д&Д используют в своей книге термин relvar как сокращенную форму от relation variable (переменная отношения).
Домены и объектные классы
Многие люди слабо разбираются в том, что такое домен. Обычно они считают, что домен - это всего лишь пул значений, из которого берутся реальные значения столбцов отношений. Этого недостаточно. Домен - это то же самое, что тип данных, возможно, определенный в систем тип (такой как INTEGER или CHAR), но в более общем случае простой определенный пользователем тип (такой как P# или QTY на рис. 1). Поэтому далее Д&Д используют термины "тип" и "домен" попеременно.
Важно понимать, что понятие типа данных включает связанное понятие операций, которые допускается применять к значениям этого типа (со значениями типа можно работать только посредством применения операций, определенных для этого типа).
Если система поддерживает домены должным образом, то ее пользователи должны иметь возможность определять собственные домены. И для домена P#, вероятно, были бы определены операции "=", "<" и т.д., но не операции "+", "*" и т.д., поскольку арифметические операции над номерами деталей, скорее всего, бессмысленны.
Тщательно различаются тип (или домен) и представление или кодировка значений этого типа внутри системы. Конечно, операции, определяемые для данного типа, зависят от смысла или семантики этого типа, а не от способа представления значений типа в системе. Представления (кодировки) значений типа должны скрываться от пользователя.
То, что говорилось выше, называется в языках программирования строгой типизацией. Для Д&Д это означает, что (a) у каждого значения имеется тип и (b) при попытке выполнения любой операции система проверяет, что операнды имеют типы, правильные для этой операции.
До сих пор ничего не говорилось о природе значений, принадлежащих домену. Эти значения могут быть всем, чем угодно (простыми или как угодно сложными). Единственное требование: значениями домена можно манипулировать только посредством определенных для него операций.
Следующее утверждение настолько важно, что Д&Д повторяют его в другой формулировке:
Вопрос о том, какие поддерживаются типы данных ортогонален вопросу поддержки реляционной модели.
Итак, в реляционном мире домен - это тип данных, определяемый системой или пользователем, обладающий произвольной внутренней сложностью, и значениями этого типа можно манипулировать только с помощью определенных для него операций. Объектный класс обладает точно такими же характеристиками. Другими словами, домены и объектные классы - это одно и то же. Поэтому Д&Д уверены, что при должной поддержке доменов реляционные системы смогут управлять всеми видами данных, которыми могут управлять объектные системы, но реляционные системы смогут управлять и такими видами данных, которыми не могут управлять объектные системы (временные ряды, биологические и финансовые данные и т.д.). Истинная "объектно/реляционная" система - это ни что иное, как истинная реляционная система.
Хочу заметить, что здесь c Д&Д можно поспорить. Конечно, при отсутствии общепринятой объектной модели можно считать, что класс - это то же самое, что тип данных. Но достаточно часто либо (a) понятие класса нагружается еще и смыслом "контейнера", хранящего все существующие экземпляры (объекты) класса, либо (b) одновременно поддерживаются понятия и типа данных, и класса объекта в разных смыслах. И это только небольшая часть возражений, которые я мог бы предъявить Д&Д от имени "объектного мира".
Relvars и объектные классы
В предыдущем разделе был поставлен знак равенства между объектными классами и доменами. Однако многие считают, что объектным классам соответствуют relvars. Д&Д считают это серьезной логической ошибкой. Из чего она проистекает?
Рассмотрим следующее определение класса на гипотетическом объектном языке:
CREATE OBJECT CLASS EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY CHAR (20) , WORKS_FOR CHAR (20) ) … ;
Здесь EMP#, ENAME и т.д. - это переменные экземпляра (называемые также членами или атрибутами), значения которых в каждом "экземпляре" класса EMP в любой момент времени составляют общее значение этого экземпляра в данный момент времени. В "чистой" объектной системе эти переменные экземпляра являются частными (т.е. скрытыми от пользователя), но в следующем ниже обсуждении предполагается, что они "публичные".
Вообще говоря, это не является принципиальным. Во многих объектных системах объявление публичной переменной экземпляра трактуется как неявное определение двух неявных методов соответствующего класса "get" и "set" для каждой такой переменной. Если говорить не слишком строго, то при использовании надлежащего подхода наличие публичных переменных не противоречит принципам инкапсуляции.
Теперь рассмотрим простое реляционное определение relvar на языке SQL:
CREATE TABLE EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY CHAR (20) , WORKS_FOR CHAR (20) ) ;
Эти два определения выглядят очень похоже, наводя на мысль, что определяется одно и то же. Однако второе определение допускает ряд возможных расширений (приводимые расширения основаны на конкретном коммерческом продукте, название которого Д&Д не оглашают, но судя по общему направлению дискуссии, это Informix Universal Server).
Первое расширение состоит в допущении составных столбцов, значениями которых являются строки, т.е. значениями столбцов могут быть строки другой (или той же самой) relvar. Например, исходное определение EMP можно заменить на следующее:
CREATE TABLE EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY CHAR (20) , WORKS_FOR CHAR (20) ) ; CREATE TABLE ACTIVITY ( NAME CHAR (20) , TEAM INTEGER ) ; CREATE TABLE COMPANY ( NAME CHAR (20) , LOCATION CITYSTATE ) ; CREATE TABLE CITYSTATE ( CITY CHAR (20 ) , STATE CHAR (2) ) ;
Сразу заметим, что это противоречит жесткому требованию Д&Д того, что relvar не является доменом.
Первое расширение является грубой аналогией той концепции, которая позволяет объектам содержать другие объекты, иногда называемой концепцией иерархии объектов. Хотя Д&Д характеризуют первое расширение как "столбцы, содержащие строки", по их мнению, более точно было бы говорить про "столбцы, содержащие указатели на строки" (более подробно см. ниже).
Аналогичные замечания относятся к второму возможному расширению, в котором допускаются столбцы со значениями-отношениями, т.е. столбцы, значениями которых являются множества строк из некоторой другой (или той же самой) relvar. Например, если у каждого служащего может быть несколько хобби, то определение EMP могло бы выглядеть следующим образом:
CREATE TABLE EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY SET OF ( ACTIVITY) , WORKS_FOR COMPANY ) ;
Третье расширение допускает наличие методов, ассоциированных с relvars (термин "метод" является обычной для объектного мира заменой термина "операция"). Например,
CREATE TABLE EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY SET OF ( ACTIVITY) , WORKS_FOR COMPANY ) METHOD RETIREMENT_BENEFITS ( ) : NUMERIC ;
Программный код, релизующий метод, можно было бы написать, например, на языке Си.
Наконец, еще одно расширение допускает определение подклассов. Например, допускаются следующие определения:
CREATE TABLE PERSON ( SS# CHAR (9) , BIRTHDATE DATE , ADDRESS CHAR (50) ) ; CREATE TABLE EMP AS SUBCLASS OF PERSON ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY SET OF ( ACTIVITY) , WORKS_FOR COMPANY ) METHOD RETIREMENT_BENEFITS ( ) : NUMERIC ;
Теперь EMP обладает тремя дополнительными столбцами, унаследованными от PERSON. Если бы у PERSON были методы, они были бы также унаследованы. Таблицы PERSON и EMP представляют пример того, что называется супертаблицой и подтаблицей соответственно.
Конечно, при наличии таких расширительных определений потребовались бы и манипуляционные расширения, например:
Сколько места потребовалось для краткого обзора того, как идея "relvar = класс" воплощается на практике! И что же здесь неправильно?
Прежде всего это неправильно, поскольку relvar - это переменная, а класс - это тип. Равно как значение отношения не есть домен, так и relvar - не есть домен. Уже из этого видно, что идея проваливается. Но можно привести еще несколько соображений:
Вот еще ряд вопросов по тому же поводу:
Все это следует из того, что мы вышли за пределы реляционной модели, в которой фундаментальным объектом является отношение, содержащее значения. В нашем случае "отношение" содержит значения и указатели. Другими словами, мы подорвали концептуальную целостность реляционной модели.
На самом деле, ясно, что когда люди отождествляют relvars и классы, они имеют в виду базовые relvars и забывают про порождаемые. На проводить различие между базовыми и порождаемыми relvars - это серьезнейшая ошибка.
Заметим, что это не очень сильное замечание, поскольку, теоретически никто не мешает разрешить определять методы при определении представления. Другое дело, что SQL-92 позволяет использовать запросы в разделе FROM запроса, и тогда действительно приходится иметь дело с чисто порождаемыми relvars, для которых негде определять методы (не делать же это прямо в тексте запроса).
Можно подвести следующий итог этого раздела. Очевидно, что можно построить систему на основе ложной идеи "relvar = класс" и, более того, такие системы уже существуют. Но также очевидно, что эти системы напоминают автомобиль без масла или дом, построенный на песке: они могут быть даже полезны на некоторое время, но в конце концов обречены на неудачу.
Замечание по поводу наследования
В разделе "Домены и объектные классы" не упоминается возможность наследования не потому, что Д&Д не хотели этого, а вследствие отсутствия четко определенной и общепринятой модели наследования ко времени написания книги. Поэтому предполагается условная поддержка наследования в том смысле, что "если наследование поддерживается, то оно должно соответствовать некоторой правильно определенной и общепризнанной модели".
Заключительные замечания
По мнению Д&Д в объектной технологии имеется одна безусловно хорошая идея - определяемые пользователями типы (включая определяемые пользователями операции). Одна идея является вероятно хорошей - наследование типов. Ключевой идеей Д&Д является то, что эти две идеи полностью ортогональны реляционной модели. Чтобы достичь объектной функциональности, с реляционной моделью не требуется делать абсолютно ничего. Что требуется от поставщиков, это чисто реляционные СУБД (это не означает "SQL-ориентированные системы) с должной поддержкой доменов, и тогда мы получим желаемые "объектно/реляционные" системы.
Я тоже хочу сделать некоторые замечания. Мне кажется, что материал первых двух глав книги очень силен в негативном смысле. Почти со всеми отрицательными утверждениями Д&Д трудно спорить. Что же касается положительных утверждений, например, в пользу отождествления доменов и классов, то они опираются на ограниченное и нечетко выраженное понимание объектов. Фактически сначала утверждается, что класс - это то же, что и тип данных (слишком сильное для объектного мира предположение), а потом, естественно, оказывается, что домен = класс. Довольно тавтологично, не правда ли? Нет никаких объектов, есть только типизированные значения и переменные, а раз так, то нет и объектно-ориентированного подхода.
Литература