Статьи

3 подхода к объектно-реляционным БД: PostgreSQL, Oracle и Informix

PostgreSQL против Informix

Вероятно, ближайшая к Postgres объектная база данных — это Informix. Informix фактически получил свой объектно-реляционный подход с покупкой Illustra, форка Postgres. Однако Illustra отделилась от Postgres до того, как последний принял SQL, и поэтому реализации SQL полностью независимы.

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

Методы таблицы

Мне не удалось найти информацию о нотации class.method в документации Informix. Насколько я могу судить, Informix требует, чтобы методы вызывались с использованием синтаксиса функции (объекта). Это похоже на пример обработки изображений Stonebraker’а
. Таким образом, связь между структурой и функцией выглядит несколько более сложной, чем в PostgreSQL. Однако было бы ошибкой рассматривать это как совокупность объектно-реляционных возможностей Informix.

наследование

Informix поддерживает одиночное наследование для обоих типов и таблиц, используя синтаксис UNDER. ПОД, аналогично INHERITS в PostgreSQL, устанавливает отношение «is-a» между супертипом и подтипом. В отличие от PostgreSQL, индексы и ссылочная целостность наследуются в Informix, что означает, что внешние ключи работают правильно в обоих направлениях. Таким образом, одиночное наследование является более зрелым в Informix, чем в PostgreSQL, но отсутствие множественного наследования препятствует составлению таблиц с помощью встроенных атрибутов типа (что возможно в PostgreSQL, но не в Informix).

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

Вернуть результаты

Select * from parent_table в Informix возвращает все атрибуты всех строк родительской таблицы и всех дочерних таблиц. Это может привести к ситуации, когда результирующий набор будет «зубчатым» (т. Е. Когда строки имеют различное количество элементов), когда дочерние таблицы добавляют дополнительные столбцы. В этом случае необходимо проверить определение строки при получении каждой строки.

Один из способов взглянуть на это состоит в том, что и PostgreSQL, и Informix возвращают набор объектов, бот PostgreSQL приводит их к запрашиваемым типам, а Informix возвращает их такими, какие они есть. Таким образом, если вы выбираете * от лица, а сотрудник наследует человека, то вы автоматически получаете всю информацию о сотруднике.

Эта функция, насколько я знаю, уникальна для Informix. Я не знаю ни одной другой ORDBMS, которая позволяла бы обрабатывать наборы результатов таким образом, но это показывает одну важную проблему, которая возникает, когда кто-то начинает объединять объектно-ориентированные и реляционные подходы. Что означает выбор * в этом случае? Это не самоочевидно, и поэтому Informix и PostgreSQL используют разные подходы.

Альтернативные подходы

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

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

Лично я считаю, что SQL, необходимый для элегантного использования столбцов как типов, несколько уродлив, но я признаю, что это личная практика. Тем не менее, учтите следующее:

SELECT print(e.name), mailing_label(e.address) from employees e;

Если адрес и имя являются сложными типами, то все, что мы собираемся сделать, будет немного уродливым. Мы ничего не можем с этим поделать.

PostgreSQL и Informix против Oracle

Oracle в некотором роде демонстрирует некоторое влияние со стороны Informix, но использует подход в несколько ином направлении. Oracle в первую очередь не делает ничего, чтобы быть реляционной базой данных, и приняла подход, который избегает, а не отвечает на вопросы правильного поведения. Объекты Oracle в некотором роде напоминают подход Informix, а в некотором смысле PostgreSQL, но в целом они больше отличаются, чем тот же.

Таблицы и типы 

Объекты Oracle имеют тенденцию подходить к вопросу об эквивалентности отношений между объектами, позволяя наследовать типы, а таблицы — нет. Однако таблицы могут копировать структуры типов для своих схем. Таким образом, обычно нужно сначала создать объектную модель, а затем создать таблицы для хранения этих объектов. Этот подход устанавливает совершенно другие шаблоны и антипаттерны, чем в Informix и PostgreSQL, где сами таблицы могут наследоваться. С одной стороны, это разделяет (принудительно) таблицы, содержащие данные, и их абстрактных родителей. С другой стороны, это усложняет работу, за исключением случаев, когда сложные столбцы используются в столбцах таблицы.

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

Подходы к составу объекта

В Oracle единственный подход, который работает, состоит в том, чтобы использовать столбцы для хранения сложных типов. К счастью, эти типы могут иметь методы, поэтому SQL не так страшен, как в Informix. Ты сможешь:

select e.name.print(), e.address.mailing_label() from employees e;

Это кажется мне более читабельным.

Мне кажется, что у Oracle Objects есть два основных применения. Первый — в логической модели базы данных, хотя эту роль в некоторой степени могут взять на себя ORM. Второй и более привлекательный подход заключается в использовании Oracle Objects не для рекламируемого ими использования моделирования таких вещей, как клиенты или счета, а скорее для создания интеллектуальных типов данных для столбцов.

Например, если я хочу сохранить изображения и динамически определить, какой тип изображения мы ищем, я все равно могу сделать что-то вроде:

 SELECT id FROM slides s
 WHERE s.picture.is_of('sunset');

Это намного чище в SQL, чем эквивалентный синтаксис в Informix или PostgreSQL:

SELECT id FROM slides s
 WHERE is_of(s.picture, 'sunset');

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

Затраты на сложность, вероятно, будут стоить этого в Oracle в совершенно ином наборе случаев, чем в PostgreSQL или Informix. Эти случаи пересекаются в запросах, которые должны возвращать данные, основанные на очень сложных критериях, которые не могут быть сведены к реляционной алгебре и исчислению предикатов.

Последние мысли

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

PostgreSQL и Informix тесно интегрируют обработку объектов гораздо глубже, чем Oracle. Informix выглядит более отточенным в областях, которые он поддерживает, но PostgreSQL имеет более широкую поддержку общей идеи.

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

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