Разработка базы данных SQL для представления иерархии классов OO

Я нахожусь в процессе преобразования иерархии классов для хранения в базе данных SQL.

Оригинальный псевдо код:

abstract class Note
{
   int id;
   string message;
};

class TimeNote : public Note
{
   time_t time;
};

class TimeRangeNote : public Note
{
   time_t begin;
   time_t end;
};

class EventNote : public Note
{
   int event_id;
};

// More classes deriving from Note excluded.

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

A. Храните все заметки в одной широкой таблице

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

CREATE TABLE t_note(
   id INTEGER PRIMARY KEY,
   message TEXT,
   time DATETIME,
   begin DATETIME,
   end DATETIME,
   event_id INTEGER
);

Будущие классы, полученные из Примечание. необходимо добавить новые столбцы к этой таблице.

B. Сопоставьте каждый класс с таблицей

CREATE TABLE t_note(
   id INTEGER PRIMARY KEY,
   message TEXT
);

CREATE TABLE t_timenote(
   note_id INTEGER PRIMARY KEY REFERENCES t_note(id),
   time DATETIME
);

CREATE TABLE t_timerangenote(
   note_id INTEGER PRIMARY KEY REFERENCES t_note(id),
   begin DATETIME,
   end DATETIME
);

CREATE TABLE t_eventnote(
   note_id INTEGER PRIMARY KEY REFERENCES t_note(id),
   event_id INTEGER
);

Будущие классы, полученные из Примечание должны создать новую таблицу.

C. Используйте нормализацию базы данных и VARIANT / SQL_VARIANT

CREATE TABLE t_note(
   id INTEGER PRIMARY KEY,
   message TEXT
);

CREATE TABLE t_notedata(
   note_id INTEGER REFERENCES t_note(id),
   variable_id TEXT, -- or "variable_id INTEGER REFERENCES t_variable(id)".
                     -- where t_variable has information of each variable.
   value VARIANT
);

Будущие классы, производные от Примечание. необходимо добавить новый variable_id .

D. Есть ли лучшие варианты?

15
задан dalle 7 August 2010 в 08:55
поделиться

5 ответов

В общем, я предпочитаю объект «B» (т.е. одну таблицу для базового класса и одну таблицу для каждого «конкретного» подкласса).

Конечно, у этого есть пара недостатков: во-первых, вам нужно объединить как минимум 2 таблицы, когда вам нужно прочитать полный экземпляр подкласса. Кроме того, к «базовой» таблице будет постоянно иметь доступ любой, кому приходится работать с любыми заметками.

Но обычно это приемлемо, если только у вас нет крайних случаев (миллиарды строк, требуется очень быстрое время отклика и т. Д.).

Существует третий возможный вариант: сопоставить каждый подкласс с отдельной таблицей. Это помогает разбивать ваши объекты на разделы, но в целом требует больше усилий при разработке.

См. это для полного обсуждения.

(Относительно вашего решения "C" с использованием VARIANT: я не могу комментировать достоинства / недостатки, потому что оно выглядит как частное решение - что это такое? Transact-SQL? И я не знаком с ним).

8
ответ дан 1 December 2019 в 04:33
поделиться

Я сам был бы признателен за вариант A.

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

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

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

1
ответ дан 1 December 2019 в 04:33
поделиться

Вы рассмотрели 3 наиболее распространенных способа моделирования объектов в реляционной базе данных. Все три способа приемлемы, и у каждого есть свои плюсы и минусы. К сожалению, это означает, что нет однозначного "правильного" ответа. Я реализовывал каждый из них в разное время, и вот несколько замечаний/оговорок, которые следует иметь в виду:

Вариант A имеет тот недостаток, что при добавлении нового подкласса вы должны изменить существующую таблицу (это может быть менее приемлемо для вас, чем добавление новой таблицы). Он также имеет тот недостаток, что многие столбцы будут содержать NULL. Однако современные СУБД, похоже, гораздо лучше управляют пространством, чем старые, поэтому я никогда не беспокоился о нулях. Одним из преимуществ является то, что ни одна из операций поиска или извлечения не требует JOIN или UNION, что означает потенциально лучшую производительность и более простой SQL.

Вариант B имеет тот недостаток, что если вы добавляете новое свойство в свой суперкласс, вам нужно добавить новый столбец в таблицу каждого подкласса. Кроме того, если вы хотите выполнить разнородный поиск (по всем подклассам сразу), вы должны сделать это с помощью UNION или JOIN (потенциально более медленная производительность и/или более сложный sql).

Вариант C имеет тот недостаток, что все операции поиска (даже для одного подкласса) будут включать JOIN, как и большинство операций поиска. Кроме того, все вставки будут включать несколько таблиц, что сделает SQL несколько более сложным и потребует использования транзакций. Этот вариант кажется наиболее "чистым" с точки зрения нормализации данных, но я редко использую его, потому что недостаток JOIN для каждой операции обычно делает один из других вариантов более приемлемым.

2
ответ дан 1 December 2019 в 04:33
поделиться

Существует серия паттернов, известных под общим названием "Пересечение пропастей", которые я использовал в течение многих лет. Пусть вас не смущают ссылки на Smalltalk - они применимы к любому объектно-ориентированному языку. Попробуйте использовать следующие ссылки:

A Pattern Language for Relational Databases and Smalltalk
Crossing Chasms - The Static Patterns
Crossing Chasms - The Architectural Patterns

Поделитесь и наслаждайтесь.

EDIT

Ссылки на Wayback Machine на все, что мне удалось найти по паттернам Crossing Chasms: http://web.archive.org/web/20040604122702/http://www.ksccary.com/article1.htm http://web.archive.org/web/20040604123327/http://www.ksccary.com/article2.htm http://web.archive.org/web/20040604010736/http://www.ksccary.com/article5.htm http://web.archive.org/web/20030402004741/http://members.aol.com/kgb1001001/Chasms.htm http://web.archive.org/web/20060922233842/http://people.engr.ncsu.edu/efg/591O/s98/lectures/persistent-patterns/chasms.pdf http://web.archive.org/web/20081119235258/http://www.smalltalktraining.com/articles/crossingchasms.htm http://web.archive.org/web/20081120000232/http://www.smalltalktraining.com/articles/staticpatterns.htm

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

0
ответ дан 1 December 2019 в 04:33
поделиться

Описанный вами вариант «B» в значительной степени является реализацией «иерархии подкласса объектов» (Kung, 1990 http://portal.acm.org/citation.cfm?id=79213 )

По сути, это хорошо известный и понятный метод. Работает неплохо. Он также расширяется за счет нескольких уровней наследования, если вам это нужно.

Конечно, вы теряете некоторые преимущества инкапсуляции и сокрытия информации, если не ограничиваете круг лиц, имеющих доступ к данным, хотя интерфейс СУБД.

Однако вы можете получить к нему доступ одновременно из нескольких систем и даже языков (например, Java, C ++, C #). (Это было предметом моей магистерской диссертации :)

3
ответ дан 1 December 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: