Оптимальная структура БД для объекта дополнительных полей - PullRequest
6 голосов
/ 09 декабря 2008

У меня есть таблица в БД (на основе Postgres), которая действует как суперкласс в объектно-ориентированном программировании. У него есть столбец «тип», который определяет, какие дополнительные столбцы должны присутствовать в таблице (свойства подкласса). Но я не хочу, чтобы таблица включала все возможные столбцы (все свойства всех возможных типов).

Поэтому я решил создать таблицу, в которую будут входить столбцы «ключ» и «значение» (т. Е. «Имя файла» = «/ файл» или «some_value» = «5»), которые содержат любое возможное свойство объекта , не включенный в таблицу суперкласса. А также сделал одну связанную таблицу для хранения доступных значений «ключа».

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

Ответы [ 8 ]

10 голосов
/ 09 декабря 2008

Дизайн, с которым вы экспериментируете, представляет собой вариант Entity-Attribute-Value , и он сопровождается целым рядом проблем и неэффективностей. Это не хорошее решение для того, что вы делаете, кроме как в крайнем случае.

Что может быть лучшим решением, это то, что описывает fallen888: создайте таблицу «подтипов» для каждого из ваших подтипов. Это нормально, если у вас есть конечное количество подтипов, что звучит так, как у вас. Тогда ваши специфичные для подтипа атрибуты могут иметь типы данных, а также ограничение NOT NULL, если это уместно, что невозможно, если вы используете дизайн EAV.

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

edit: Что касается вашей дополнительной информации о комментариях к любому объекту, то да, это довольно распространенная модель. Остерегайтесь неработающего решения, называемого «полиморфная ассоциация», которое многие люди используют в этой ситуации.

2 голосов
/ 09 декабря 2008

Как насчет этого ... каждый подтип получает свою собственную таблицу БД. А в таблице base / super просто есть столбец varchar, в котором содержится имя таблицы DB подтипа. Тогда вы можете получить что-то вроде этого ...

Entity
------
ID
Name
Type
SubTypeName   (value of this column will be 'Dog')


Dog
---
VetName
VetNumber
etc

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

0 голосов
/ 31 января 2009

извините, я написал 19079 выше, я имел в виду 1979 год. Oracle получила свой первый контракт на написание базы данных для ЦРУ.

0 голосов
/ 31 января 2009

о том, что пользователь может добавить новое поле в таблицу:

Я восхищаюсь всеми этими людьми, делающими комментарии.

Раньше я интересовался такими вещами несколько лет назад, но недавно написал немного кода (кроме небольшого количества PHP и MYSQL).

Я думаю, что все в порядке, если вы хотите продолжать - у вас может получиться что-то новое.

Извините, что наливаю любую холодную воду по схеме - я восхищаюсь вашими усилиями. Мое личное убеждение заключается в том, что если вы зайдете достаточно далеко в этом направлении, вы получите систему, которая интерпретирует больше естественного языка, чем SQL. (Примерно в 1970 году SQL фактически назывался Sequel, и он фактически обозначал «структурированный английский язык запросов», но после того, как они стандартизировали его в 1970-х годах - я думаю, что кто-то сказал, что Oracle была первой коммерческой реализацией, 19079, «английский» получил упал, потому что, я думаю, они решили, что это всего лишь небольшое подмножество английского языка.

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

Наилучшие пожелания всем.

0 голосов
/ 09 декабря 2008

Спасибо за ответы. Я объясню немного более конкретно, что мне нужно. Необходимо запрограммировать сайт «блог + форум», и я изучаю структуру WordPress DB .

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

Но еще не поздно изменить это, потому что это на ранней стадии разработки. Также наша модель теперь пахнет как полностью основанная на древовидной иерархии БД. Сейчас я приму ответов Билла Карвина и fallen888 , но, может быть, я иду в совершенно неверном направлении?

0 голосов
/ 09 декабря 2008

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

Это похоже на крайне неэффективную архитектуру для реляционных баз данных на основе строк.

Возможно, вам стоит взглянуть на реляционную базу данных, ориентированную на столбцы?

0 голосов
/ 09 декабря 2008

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

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

0 голосов
/ 09 декабря 2008

Единственный обходной путь (при сохранении структуры) - иметь отдельные таблицы:

create table IntProps(...);
create table StringProps(...);
create table CurrencyProps(...);

Но я не думаю, что это хорошая идея ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...