Классика баз данных - статьи

         

Мы представляем манифест о направлениях


Эта работа представляет собой манифест, касающийся будущего систем управления данными и СУБД. Название манифеста обусловлено тем, что он следует за двумя предшествующими манифестами [1,25] и, как мы надеемся, сможет заменить их. Отсюда наш выбор названия. В [1] презрительно отвергается реляционная модель данных и игнорируется ее важность и значимость. Вместе с тем, как мы полагаем, ее авторам не удалось определить какую-либо четкую линию. В [25] реляционной модели вежливо отдается должное, но в излишне оптимистичной погоне за ее идеалами не упоминается и не подчеркивается безнадежность продолжения следования широко распространенному извращению этой модели, воплощенному в SQL. В отличие от этого, мы твердо убеждены – в любой попытке двигаться вперед для того, чтобы выдержать испытание временем, необходимо недвусмысленно отвергнуть SQL. Однако на самом деле мы уделяем некоторое внимание вопросу о том, что следует делать с сегодняшним наследием SQL.



Назад к будущему


Мы ищем прочные основы для будущего управления данными. При этом мы не считаем, что такие основы способен обеспечить язык баз данных SQL. Вместо этого мы полагаем, что любые такие основы должны твердо корениться в реляционной модели данных, впервые представленной миру Э.Ф.Коддом в 1969 году в [6].

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

Допустим, что такой язык имеется и называется D.

Язык D будет предметом определенных предписаний и запретов. Некоторые из этих предписаний проистекают из реляционной модели данных, и мы будем называть их предписаниями реляционной модели, или для краткости – РМ-предписаниями. Предписания, которые не происходят из реляционной модели, назовем остальными ортогональными предписаниями, или для краткости – ОО-предписаниями. Подобным же образом мы категоризируем запреты для языка D.

Перейдем теперь к более подробному обсуждению предписаний и запретов языка D. Следует заметить, что РМ-предписания и запрещеты не могут быть предметом компромисса. К сожалению, этого совсем нельзя сказать по поводу ОО-предписаний и запрещетов, поскольку не существует (во время написания этой работы) ясной и общепринятой модели, на которой они могли бы базироваться. На самом деле мы полагаем, что ОО может внести значительный вклад в области типов данных, определяемых пользователями, и наследования. Однако пока не достигнут какой-либо консенсус относительно абстрактной модели даже относительно этих важных предметов.
Поэтому мы вынуждены дать наши собственные определения в этих областях. И лишь справедливо будет предупредить читателя, что наследование, по меньшей мере, порождает ряд вопросов, на которые, как нам представляется, пока еще нет удовлетворительных ответов в доступной литературе. В результате в настоящее время наши предложения в этой области должны по необходимости быть в некотором роде предварительными (см. ОО-предписания 2 и 3).

Наряду с предписаниями и запретами этот манифест включает также некоторые весьма настоятельные предложения, также подразделяющиеся на РМ- и ОО-категории.

Три последние предварительные замечания.

Если говорить совсем точно, то версия реляционной модели, которую мы поддерживаем, – это версия, впервые описанная в [16] (глава 15) и позже уточненная (в небольшой степени) в [11] (часть II). Заметим, однако, что определения кортежа и отношения в данной работе представляют собой немного улучшенные варианты определений, приведенных в указанных ранних публикациях.

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

В тех случаях, когда это недостаточно очевидно, мы хотели бы, чтобы было предельно ясно, что главная сфера наших интересов – это абстрактная модель, а не вопросы реализации (хотя в целях обеспчения ясности пояснительные комментарии касаются иногда и таких вопросов).


ОО-предписания


В языке D должна допускаться проверка типов на стадии компиляции.

Комментарии:

В этом предписании имеется в виду, что в той мере, в какой это осуществимо, следует выполнять проверку на стадии компиляции с тем, чтобы на стадии исполнения никакие ошибки типов не имели места. Это требование не исключает возможности "откомпилировать и исполнить" (compile and go), а также реализаций на основе интерпретации.

(Простое наследование (Single Inheritance)) Если язык D позволяет определять некоторый домен V' как поддомен некоторого супердомена V, то такая возможность должна соответствовать некоторой ясно определенной и общепринятой модели.



Комментарии:

Наша надежда заключается в том, что такая "ясно определенная и общепринятая" модель наследования когда-нибудь будет действительно найдена. Термин "общепринятая" призван здесь подчеркнуть, что авторы настоящего манифеста наряду с другими выступают в поддержку такой модели. От такой поддержки нет оснований отказываться.

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

(Множественное наследование (Multiple Inheritance) Если в языке D допускается определение некоторого домена V' как поддомена какого-либо супердомена V, то не следует препятствовать также и тому, чтобы V' мог быть дополнительно определен как поддомен и некоторого другого супердомена W, который не совпадает с V и не является каким-либо его супердоменом (если только требования ОО-предписания 2 не исключают такую возможность).

Язык D должен обладать вычислительной полнотой. Это означает, что D может (но не обязан) поддерживать вызовы из так называемых "основных программ" (host program), написанных на языках, отличных от D.
Подобным же образом, D может ( но не обязан) поддерживать использование других языков программирования для реализации функций, определяемых пользователем.

Комментарии:

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

Инициирование транзакции должно производиться только с помощью явного оператора "начать транзакцию" (start transaction). Завершение транзакции должно осуществляться только с помощью операторов "зафиксировать" (commit) или "откатить" (rollback). Оператор "зафиксировать" должен быть явным, в то время как оператор "откатить" может быть и неявным (в случае, когда транзакция завершается неудачно, хотя в самой транзакции не было никаких сбоев).

Комментарии:

Если транзакция T завершается оператором "зафиксировать" ("нормальное завершение"), то изменения, произведенные T в соответствующей dbvar, фиксируются. Если же транзакция T завершается оператором "откатить" (аварийное завершение), то изменения, произведенные T в соответствующей dbvar, анулируются.


Иными словами, dbvar ( и только они) обладают свойством "стабильности" ("persistence").

В языке D должны поддерживаться вложенные транзакции (nested transactions) – т.е. должно допускаться, чтобы какая-либо транзакция T1 могла начать другую транзакцию T2 до завершения собственного выполнения, и в этом случае:

T2 и T1 должны взаимодействовать с одной и той же dbvar (как это фактически предусматривается РМ-предписанием16).

D не должен препятствовать возможности асинхронного исполнения T1 и T2. Однако T1 не должна иметь возможности завершиться, прежде чем завершится T2 (иными словами, T2 должна полностью содержаться в T1).

Откат T1 должен включать отмену результатов T2, даже если T2 была зафиксирована.

Пусть A – некоторая агрегатная (aggregate) операция (например, операция вычисления суммы, SUM), которая, по существу, является просто краткой записью некоторой повторяемой диадической операции θ – (в случае SUM такой диадической операцией является "+"). Если аргумент A оказывается пустым, то:

если для θ существует значение тождественности (в случае "+" значением тождественности является 0), то результатом такого вызова A должно быть это значение тождественности;

в противном случае результат такого вызова A должен быть не определен.


ОО-запреты


Relvar не являются доменами.

Комментарии:

Иными словами, мы категорически отвергаем равенство вида "отношение = объектный класс" (более точно, равенство "relvar = объектный класс"), отстаиваемое, например, в [23]).

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

Комментарии:

Иными словами, мы отвергаем идею "объектных идентификаторов" (object ID). Как следствие этого, мы отвергаем: a) идею о том, что "объекты" могли бы использовать такие идентификаторы для совместного использования "подобъектов"; b) идею о том, что пользователи могли бы вынуждаться "разыменовывать" (dereference) такие идентификаторы (либо явно, либо неявно), чтобы получать значения.

Мы отвергаем также идею "идентификаторов кортежей" (tuple ID) (некоторые авторы, как нам кажется, отождествляют идентификаторы кортежей и объектные идентификаторы).

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

Любая нотация "публичной переменной экземпляра" (public instance variable), обеспечиваемая для оперирования значениями в доменах, должна быть всего лишь сокращенной синтаксической формой для вызова некоторых специальных функций (и возможно, “ссылок на псевдопеременные”, если такие переменные экземпляра могут появляться в левой части операций присваивания). Какая-либо непосредственная взаимосвязь между такими переменными экземпляра и реальным представлением значений из соответствующего домена не должна иметь обязательного характера.

В D не должна поддерживаться ни концепция "защищенных" (protected) переменных экземпляра (в отличие от приватных (private)), ни концепция "друзей" (friends). Пояснение этих понятий см. [20].

Комментарии:

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


Relvar не являются доменами

Никаких идентификаторов объектов

Никаких "публичных переменных экземпляра"

Никаких "защищенных переменных экземпляра" или "друзей"



РМ-предписания


Домен – это именованное множество значений. Манипулирование такими значениями, которые могут быть произвольной сложности, должно быть возможно исключительно посредством операций, определенных для этого домена (этих доменов) (см. РМ-предписание 3 и ОО-предписание 3), т.е. значения домена должны быть инкапсулированы (за исключением тех случаев, которые отмечаются в РМ-предписании 4). Для каждого домена должна быть доступна нотация, позволяющая явно специфицировать (или "конструировать") произвольное значение из этого домена.

Комментарии:

Мы интерпретируем термины домен и тип данных (для краткости тип) как синонимичные и взаимозаменяемые. В том же самом смысле используется иногда термин объектный класс, но мы не используем этот более поздний термин.

Обобщенно мы называем значения домена скалярными значениями (или для краткости скалярами). Заметим, следовательно, что мы явно допускаем "скалярные" значения произвольной сложности. Таким образом, например, массив стеков списков и т.д. в соответствующих обстоятельствах может рассматриваться как скалярное значение.

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

Для каждого упорядоченного списка n доменов, не обязательно различных (n ≥ 0), в D должны поддерживаться определения допустимых n-адических операций, которые применимы к соответствующим упорядоченным спискам из n значений, взятых по одному из каждого из этих n доменов. Определение каждого такого оператора должно включать спецификацию домена результата этой операции. Определения таких операций должны быть логически отделены от определений доменов, к которым они относятся (а не быть "встроенными" в эти определения).

Комментарии:

Мы интерпретируем термины операция и функция как синонимичные и взаимозаменяемые. В этом же смысле иногда применяется термин метод, однако мы не используем этот более поздний термин.


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

Пусть V – некоторый домен. В состав определенных для V операций должны обязательно входить такие операции, явным назначением которых является раскрытие действительных представлений (actual representation) значений из V. Заметим, что эти операции – и только они – нарушают, таким образом, инкапсуляцию значений из V.

Комментарии:

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

Пусть V – некоторый домен. Отметим, что часто будет желательно определить набор операций, действие которых состоит в том, чтобы раскрыть одно возможное представление (possible representation) (не обязательно фактическое представление) для значений из V. При наличии таких операций пользователь по сути будет способен оперировать значениями из V точно так же, как если бы он имел дело с фактическим представлением.

Хотя реальные представления значений домена не существенны для спецификаций данного манифеста, может быть полезно указать, что, если v1 и v2 – разные значения из домена V, ничто в языке D не требует, чтобы реальные представления v1 и v2 были бы одной и той же формы. Например, V может быть доменом "текст", а v1 и v2 – двумя документами, подготовленными с использованием разных текстовых процессоров.

D должен поставляться оснащенным некоторыми стандартными (встроенными) доменами, включающими, в частности, домен истинностных значений (true и false). Для этого домена должны поддерживаться обычные операции (NOT, AND, OR, IF ...


THEN ..., IFF и т.д.).

Пусть H – некоторый заголовок кортежа (tuple heading) (см. РМ-предписание 9). Тогда должна существовать возможность определить домен, значения которого являются кортежами с заголовком H, – иными словами, TUPLE

должен быть допустимым конструктором типов. Определенные для такого домена операции должны в точности составлять набор операций над кортежами (tuple operators), поддерживаемых D. Он включает операцию конструирования кортежа из указанных скаляров, а также операцию извлечения из кортежа указанных скаляров. Должны также включаться средства "вкладывания" и "выкладывания" ("nest"/"unnest") кортежей, аналогичные подобным средствам для отношений, описанным в [16] (глава 6).

Пусть H – некоторый заголовок отношения (см. РМ-предписание 10). Тогда должна существовать возможность определения домена, значениями которого являются отношениями с заголовком H. Иными словами, RELATION

должен быть допустимым конструктором типов. Операции, определенные для такого домена, должны в точности представлять собой множество операций над отношениями, поддерживаемых D. В их число должна входить операция конструирования отношения из указанных кортежей, а также операция извлечения из отношения указанных кортежей. Должны иметься также возможности "вкладывания" и "выкладывания" ("nest"/"unnest") вложенных отношений, описанные в [16] (глава 6).

Комментарии:

Заметим, что с точки зрения любого отношения, которое включает атрибут, определенный на таком домене, "скалярные" значения в этом домене (как и значения всех доменов) по-прежнему являются инкапсулированными. (Аналогичное замечание относится также к РМ-предписанию 6.) Мы не поддерживаем в явном виде отношения в форме NF2 ("NF в квадрате"), описанной, например, в [24], которая влечет существенные расширения классической реляционной алгебры.

Для каждого домена должен быть определен оператор сравнения на равенство (equals, "=").


Пусть v1 и v2 – некоторые значения из какого- либо домена V. Тогда v1 = v2 должно быть истинно тогда и только тогда, когда v1 и v2 являются одним и тем же элементом V.

Кортеж t – это множество упорядоченных триплетов вида <A,V,v>, где:

A – имя атрибута t. Никакие два различных триплета в t не должны содержать одно и то же имя атрибута;

V – имя (единственного) домена, соответствующего атрибуту A;

v – некоторое значение из домена V, называемое значением атрибута

A в кортеже t.

Множество упорядоченных пар <A,V>, которое получается в результате исключения компонента (значения) v из каждого триплета в t, представляет собой заголовок t. При заданном заголовке кортежа должна быть доступна нотация, позволяющая явно специфицировать (или "сконструировать") произвольный кортеж с таким заголовком.

Отношение R состоит из заголовка и тела. Заголовок R – это заголовок кортежа H, определенный в РМ-предписании 9. Тело R – это множество B кортежей таких, что все они имеют заголовок H. Атрибуты и соответствующие домены, указанные в H, – это атрибуты и соответствующие им домены R. При заданном заголовке отношения должна быть доступна нотация, позволяющая явным образом специфицировать (или "сконструировать") произвольное отношение с этим заголовком.

Комментарии:

Заметим, что каждый кортеж в R содержит в точности одно значение v для каждого атрибута A в H. Иными словами, R находится в первой нормальной форме – 1NF.

Мы проводим строгое различие между отношениями самими по себе и переменными отношений (см. РМ-предписание13). Аналогичное различие относится также и к базам данных (см. РМ-предписание15). Мы осознаем, что эти терминологические различия будут, к сожалению, непривычны большинству читателей. Тем не менее мы принимаем их в интересах точности.

Скалярная переменная типа V – это переменная, допустимыми значениями которой являются скаляры из указанного домена V – объявленного домена (declared domain) для этой скалярной переменной.


Создание скалярной переменной S должно приводить к инициализации S некоторым начальным скалярным значением – либо значением, явно специфицированным в операции создания S, либо некоторым значением, зависящим от реализации, если никакое значение явно не указано.

Кортежная переменная (tuple variable) типа H – это переменная, допустимыми значениями которой являются кортежи со указанным заголовком кортежа H – объявленным заголовком (declared heading) для этой кортежной переменной. Создание кортежной переменной T должно приводить к инициализации T некоторым начальным кортежным значением – либо значением, явно специфицированным в операции создания T, либо некоторым значением, зависящим от реализации, если никакое значение явно не указано.

Переменная отношения (relation variable) – для краткости R-переменная (relvar) – типа H – это переменная, допустимыми значениями которой являются отношения с указанным заголовком отношения H

объявленным заголовком для этой relvar.

Relvar могут быть базовыми (base) либо производными (derived). Производная relvar – это такая relvar, значение которой в любой заданный момент времени представляет собой отношение, определяемое посредством заданного реляционного выражения (см. РМ-предписания 18-20). Это реляционное выражение должно быть таким, чтобы производная relvar обновлялась в соответствии с правилами и принципами, описанными в [11] (глава 17) и [18-19]. Базовая relvar – это relvar, которая не является производной. Создание базовой relvar должно приводить к инициализации этой базовой relvar некоторым пустым отношением.

Комментарии:

Базовые и производные relvar соответствуют тому, что обычно называется "базовыми отношениями" и "обновляемыми представлениями" соответственно. Заметим, однако, что мы считаем обновляемыми значительно более широкую категорию представлений по сравнению с традиционными подходами [18-19].

Переменная базы данных (database variable) – для краткости dbvar – это именованное множество relvar.


Каждая dbvar является предметом набора ограничений целостности (см. РМ-предписания 23 и 24). Значение данной dbvar в любой заданный момент времени представляет собой множество упорядоченных пар <R,r> (где R – имя relvar, а r

– текущее значение этой переменной) таких, что: a) в этой dbvar существует одна такая упорядоченная пара для каждой relvar; b) эти значения relvar одновременно удовлетворяют соответствующим ограничениям. Такое значение dbvar называется базой данных (иногда состоянием базы данных, но мы не используем этот более поздний термин).

Комментарии:

Стоит обратить внимание на то, что мы явно не считаем, что домены относятся к какой-либо конкретной dbvar.

Каждая транзакция взаимодействует в точности с одной dbvar. Однако разные транзакции могут взаимодействовать с разными dbvar, и разные dbvar не обязательно являются непересекающимися. Кроме того, транзакция может динамически изменять ассоциированную с нею dbvar, добавляя и/или удаляя relvar (см. РМ-предписание 17).

Комментарии:

Одно из назначений понятия dbvar заключается в том, чтобы определить область действия реляционных операций. Другими словами, если dbvar X ассоциирована с транзакцией T, то в T не должны использоваться ссылки на какую-либо relvar, которая входит в какую-либо иную dbvar, а не в dbvar X.

Множество всех базовых relvar может рассматриваться как "базовая" dbvar. Однако отдельные транзакции взаимодействуют с "производными" или "пользовательскими" dbvar, которые, вообще говоря, состоят из комбинации базовых и производных relvar.

В данном манифесте не специфицируется механизм установления и разрыва связей между транзакцией и соответствующей ей единственной dbvar.

В языке D должен обеспечиваться операции для создания (create) и разрушения (destroy) доменов, переменных (в том числе relvar) и ограничений целостности. Каждые явно созданные домен, переменная или ограничение целостности должны быть именованными. Каждая базовая relvar должна иметь, по крайней мере, один возможный ключ (candidate key), явно специфицированный в той операции, которая создает эту базовую relvar.



Комментарии:

Создание и разрушение dbvar (которые, как мы предполагаем, должны быть "стабильными" (persistent) осуществляется вне среды языка D.

Выразительные средства реляционной алгебры в том виде, как она определена в [11] (часть II), должны быть избавлены от чрезмерной многоречивости.

Комментарии:

"Отсутствие чрезмерной многоречивости" предполагает, помимо прочего, что:

должны в равной мере легко выражаться кванторы всеобщности и существования. Например, если язык D включает специальную операцию реляционной проекции (projection) отношения, то он должен также включать и специальную операцию для поддержки общей формы реляционного деления (division) отношений, описанной (как DIVIDEBY PER) в работе [16] (глава 11);

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



Как имена relvar, так и явные ("сконструированные") значения отношений, должны быть допустимыми реляционными выражениями.

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

Комментарии:

Функции такого рода соответствуют тому, что обычно называется "представлениями только для чтения" (read-only views), за исключением того, что мы допускаем параметризацию реляционных выражений, определяющих подобного рода "представления". Такие параметры представляют собой скалярные значения и допустимы в определяющем реляционном выражении везде, где допускаются в явном виде скалярные значения. (Вероятно, окажется возможно поддерживать также параметры – кортежи и отношения. См. Весьма настоятельное РМ-предложение 7).

В языке D должны допускаться:

присваивание значения кортежного выражения кортежной переменной;



присваивание значения реляционного выражения relvar

с обеспечением в обоих случаях удовлетворение требований совместимости типов

(type compatibility) в том виде, как они описаны в [11] (глава 19).

Комментарии:

Это предписание, конечно, не отвергает возможности дополнительного обеспечения удобных кратких обозначений такого рода, как INSERT, UPDATE и DELETE, описанных в [11} (часть II).

В языке D должны поддерживаться определенные операции сравнения. Операциями, определенными для сравнения кортежей, должны быть лишь "=" и "≠". Операции, определенные для сравнения отношений, должны включать "=", "≠", "является подмножеством" и т.д. Также должна поддерживаться операция "∈" , позволяющая проверить, является ли кортеж элементом отношения. Во всех случаях должны удовлетворяться требования совместимости типов, описанные в [11] (глава 19).

Любое выражение, значением которого является истинностное значение, называется условным выражением (conditional expression). Любое условное выражение, которое является замкнутой правильно построенной формулой (closed WFF) реляционного исчисления (или логически эквивалентно ей) [11] (часть II), должно быть допустимо в качестве спецификации ограничения целостности. Ограничения целостности должны классифицироваться в соответствии со схемой, описанной в [11] (глава 16) и [18-19], как ограничения доменов, атрибутов, отношений и базы данных, и в языке D должен полностью поддерживаться механизм вывода ограничений (constraint inference), предусматриваемый этой схемой.

У каждой relvar имеется соответствующий предикат отношения (relation predicate), и у каждой dbvar – соответствующий предикат базы данных (database predicate), которые разъясняются в [11] (глава 16) и [18-19]. Предикаты отношений долны удовлетворяться на границах операций. Предикаты базы данных должны удовлетворяться на границах транзакций.

Комментарии:

На эти понятия, которые как мы полагаем, являются и весьма существенными, и фундаментальными, к сожалению, в прошлом не обращалось должного внимания, и поэтому мы немного затрагиваем здесь эту тему.


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

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

Из этого предписания, кроме того, следует, что должно быть невозможно обновлять "обновляемые представления" (т.е. производные relvar) таким образом, чтобы нарушалось определение этого представления. Иными словами, "обновляемые представления" всегда должны быть предметом того, что в SQL называется CASCADED CHECK OPTION [17].

Каждая dbvar должна включать набор relvar, которое составляет каталог этой dbvar. Должна иметься возможность осуществлять присваивание relvar каталога.

Комментарии:

Из этого предписания следует, что каталог должен представлять собой нечто, что обычно называется "самоописанием".

D должен конструироваться в соответствии с твердо утвердившимися принципами правильной разработки языка, описанными, например, в [3].

Комментарии:

Таким образом, должны быть абсолютно исключены произвольные ограничения, например, такие, как описаны в [8] (глава 12), [14] и [17], а также все другие случайные понятия и конструкции.


РМ-запреты


Внимательный читатель заметит, что многие из запрещений в этом разделе являются логическими следствиями РМ-предписаний. Однако в связи с теми ошибками, которые были, к сожалению, допущены в SQL, мы чувствуем, что для большей ясности здесь необходимо описать некоторые из этих следствий.

Язык D не должен включать никаких конструкций, которые зависят от определения какого-либо упорядочения атрибутов отношения. Вместо этого для каждого отношения R, выразимого в D, атрибуты отношения должны быть различимы по именам.

Комментарии:

Этот запрет означает, что более не допускается никаких анонимных столбцов, таких как в операторе SQL SELECT X + Y FROM T, и никаких дубликатов имен столбцов, как в операторах SQL SELECT X, X FROM T и SELECT T1.X, T2.X FROM T1, T2.

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

Комментарии:

Из этого запрета вовсе не следует, что такое упорядочение не может быть установлено, например, для целей представления. Скорее, имеется в виду, что в результате такого упорядочения отношение конвертируется в нечто, что не является отношением (возможно, в последовательность или упорядоченный список).

Для каждого отношения R, если t1 и t2 являются двумя разными его кортежами, в R должен существовать некоторый атрибут A такой, что значение атрибута A в t1 не равно значению атрибута A в t2.

Комментарии:

Иными словами, "строки-дубликаты" являются незаконными абсолютно, категорически и однозначно. То, что мы сказали здесь три раза, – справедливо.

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

Комментарии:

Иными словами, больше никаких неопределенных значений и больше никакой многозначной логики!

В D не следует забывать как то, что отношения с нулем атрибутов заслуживают внимания и представляют интерес, так и то, что возможные ключи с нулем компонентов подобным же образом заслуживают внимания и интересны.


Язык D не должен включать никаких конструкций, которые связаны с "физическим" уровнем, уровнем "среды хранения" или "внутренним" уровнем системы либо логически подвергаются их воздействию (иных, чем функции, которые явно раскрывают реальное представление значений домена – см. РМ-предписание 4). Если разработчик имеет желание или потребность ввести какого-либо рода "язык определения структуры хранения", операторы этого языка и отображения dbvar в физическую среду хранения должны быть полностью отделены от всего, что выражается в D.

Над отношениями не должно быть никаких покортежных операций.

Комментарии:

Операции INSERT, UPDATE и DELETE, если они обеспечиваются, вставляют, обновляют или удаляют (соответственно применяемой операции) всегда множество кортежей. Множество, состоящее из одного кортежа, является просто частным случаем (хотя для такого случая может оказаться удобным предусмотреть специальный синтаксис).

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

Категорически запрещается покортежное обновление (аналогичное операциям SQL UPDATE и DELETE, выполняемым с помощью курсора).

Язык D не должен включать какой-либо специальной поддержки "составных доменов" или "составных столбцов" (как предлагается, например, в [4]), поскольку такие функциональные возможности могут достигаться, если это желательно, с помощью уже описанной поддержки доменов. См. [9].

Операторы подавления проверки доменов (в том, например, виде, как они описаны в [4]) являются случайными и не необходимыми. Они не должны поддерживаться.

Язык D не должен называться SQL.


Третий манифест


Х. Дарвин и К. Дэйт
Перевод: М.Р. Когаловский

Источник: журнал Системы Управления Базами Данных # 1/1996, издательский дом «Открытые системы»
Новая редакция: Сергей Кузнецов, 2009 г.

Оригинал: Hugh Darwen and C.J.Date. The Third Manifesto. SIGMOD Record, Vol. 24, No. 1, March 1995.



Весьма настоятельные ОО-предложения


Следует поддерживать некоторую форму наследования типов (см. ОО-предписания 2 и 3). В соответствии с этим предложением не следует допускать включения в D: a) концепции неявного преобразования типов; b) концепции, предусматривающей, что функции имеют специальный "отмеченный" (distinguished) параметр или параметр-"получатель" (receiver).

Комментарии:

Неявные преобразования типов противоречили бы достижению цели замещаемости; помеченные параметры вводили бы искусственную и не необходимую степень асимметрии. Обе эти проблемы более подробно анализируются в готовящемся к выходу приложении относительно наследования, упомянутом в ОО-предписании 2.

Следует поддерживать конструкторы типов-"коллекций", такие как LIST (список), ARRAY (массив) и SET (множество), подобно тому, как это сделано в языках, поддерживающих развитые системы типов. (См. также РМ-предписание 7.)

Пусть С – конструктор типа “коллекции”, отличный от RELATION. Тогда следует обеспечивать функцию преобразования, скажем C2R, для конвертирования значений типа C в отношения, а также обратная функция, скажем R2C, такие, что:

C2R(R2C(r)) = r для каждого отношения r, выразимого в D;

R2C(C2R(c)) = c для каждого выразимого в D значения c типа C.

DD следует основывать на модели "одноуровневого хранения", как это описано, например, в [15]. Другими словами, в этой модели не должно производиться какое-либо логическое различие между ситуациями, когда порция данных располагается в основной памяти или во вторичной или третичной (tertiary) памяти и т.д.



Весьма настоятельные РМ-предложения


Должна существовать возможность спецификации одного или более возможных ключей для каждой производной relvar. Вместе с тем для каждой relvar (базовой или производной), для которой специфицированы возможные ключи, должна иметься возможность назначения в точности одного из них первичным ключом.

Комментарии:

Каждая relvar действительно обладает одним или более возможных ключей (из которых, по крайней мере, один, а предпочтительнее все, должны назначаться пользователем в случае базовых relvar, как это требуется в RM-предписании 17). Однако назначение одного из конкретных возможных ключей первичным ключом является факультативным по причинам, обсуждаемым в [13].

В язык D следует включить поддержку системно-генерируемых

ключей, как это описано в [16] (глава 5) и [7] (глава 19).

В язык D следует включить какие-нибудь удобные краткие декларативные обозначения для выражения: a) ссылочных ограничений (referential constraints); b) ссылочных действий (referential actions), таким как "каскадное удаление".

Для системы желательно, хотя и в полной мере не осуществимо, обладать способностью выводить (независимые от времени) возможные ключи для каждого отношения R, выразимого в языке D, таким образом, что:

возможные ключи R становятся возможными ключами R', когда R присваивается R';

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

В языке D следует обеспечивать такие функциональные возможности, но без какой-либо гарантии относительно того, что выведенные ключи не являются собственными надмножествами фактических ключей, или даже что для каждого фактического ключа обнаруживается некоторое надмножество (собственное или иное). Реализации языка D могут, таким образом, состязаться друг с другом в степени успеха обнаружения возможных ключей.

Комментарии:

Рекомендация о том, что следует выводить возможные ключи для производных отношений (насколько это возможно), была фактически предложена в RM-предписании 23, в котором требовалась поддержка общего механизма вывода ограничений.
Возможные ключи упоминаются здесь явным образом, поскольку считаются важным частным случаем по причинам, обсуждаемым в [16] (глава 10).

В D следует предоставлять какие-либо удобные (непроцедурные) средства выражения запросов с квотой (quota query) (например "найти трех самых молодых служащих"). Такая возможность не должна увязываться с механизмом, который конвертирует отношение в упорядоченный список (см. РМ-запрет 2).

В D следует обеспечивать какие-либо удобные (непроцедурные) средства выражения обобщенного транзитивного замыкания графового отношения, включая возможность выполнения обобщенных операций конкатенации и агрегирования, описанных в [21].

В D следует допускать использование параметров в функциях, значениями которых являются отношения, для представления кортежей, отношений, а также скаляров.

Комментарии:

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

В D обеспечить механизм для того, чтобы иметь дело с "отсутствующей информацией" в духе схемы значений по умолчанию, описанной в [16] (глава 21), но основанной на доменах, а не на атрибутах.

Комментарии:

Термин "значение по умолчанию" может привести к заблуждению, поскольку он предполагает такую интерпретацию, которая вовсе не имеется в виду – а именно то, что данное значение появляется настолько часто, что оно может быть с таким же успехом задано по умолчанию. Намерение же, скорее, заключается в том, чтобы использовать уместное значение "по умолчанию", отличное от всех возможных истинных значений, когда ни одно из подлинных значений не может быть использовано. Например, если подлинные значения атрибута ОТРАБОТАННЫЕ_ЧАСЫ – это положительные целые числа, то задание значения по умолчанию "?" может использоваться для того, чтобы показать, что (по каким-то причинам) никакое подлинное значение не известно. Следовательно, домен для атрибута ОТРАБОТАННЫЕ_ЧАСЫ – это не просто домен положительных целых чисел.



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

Комментарии:

Из сказанного выше совсем не следует, что язык D должен быть надмножеством SQL; скорее следует предоставить возможность написания внешнего слоя кода D – надстройки над традиционными реляционными средствами D, которая:

будет воспринимать SQL-операции над конвертированными SQL- данными;

будет выдавать результаты, которые бы выдавали операции SQL, если бы они выполнялись над первоначальными не конвертированными данными SQL.

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


Заключительные замечания


Мы представили манифест относительно будущих направлений развития систем управления данными и СУБД. Теперь, вероятно, пришло время признаться, что мы действительно ощущаем некоторый дискомфорт в связи с идеей назвать некоторый по сути своей технический документ "манифестом". В соответствии со словарем XX века Чемберса, манифест – это "представленная в письменной форме декларация намерений, мнений или мотивов" некоторого лица или группы (например политической партии). Данная же конкретная декларация, напротив, является, как мы надеемся, предметом науки и логики, а не просто "намерениями, мнениями или мотивами". Однако если принять во внимание исторические прецеденты, которые привели нас к написанию этого документа, то в действительности выбор этого заголовка был предопределен.

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