2010-06-25 4 views
7

Я пытаюсь взвесить относительные преимущества и недостатки простой структуры базы данных, такие как это:Проектирование баз данных: гибкость по сравнению с простотой

1.

CREATE TABLE x (
    my_id INT PRIMARY KEY, 
    ..., 
    text_attribute_blah TEXT, 
    text_attribute_blah_blah TEXT 
); 

против:

2.

CREATE TABLE x (
    my_id INT PRIMARY KEY, 
    ... 
) 

CREATE TABLE attributes (
    my_id INT, /* foreign key to x.my_id */ 
    text_attribute_type INT, 
    text_attribute TEXT 
) 

Где атрибут_type может быть blah или blah_blah.

Вариант 1 предлагает простоту - таблица легче читать/писать; Вариант 2 предлагает гибкость (если мы хотим добавить еще один атрибут, такой как blah_blah_blah, нам не нужно изменять схему и, возможно, меньше изменений кода.)

Есть ли правильный или неправильный ответ на эту головоломку? Является ли один из этих вариантов лучшей практикой, чем другие? Можете ли вы указать мне на дальнейшее чтение, которое может помочь определить путь вперед?

+2

Гибкость переоценивается, если вы выполняете свою работу, изменения схемы должны быть редкими. В моем опыте пользователи ненавидят использование программ, которые являются «гибкими», даже если это то, что они говорят, что они хотят. – HLGEM

ответ

10

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

# 2 вариант называется EAV - Entity Атрибут Значение - и она имеет существенные недостатки - см

+1

Я добавлю эту ссылку http://www.simple-talk.com/opinion/opinion-pieces/bad-carma/ – HLGEM

+2

Остановите безумие EAV! –

2

Вариант 1 почти каждый раз. Вариант 2 очень неэффективен. Это также довольно неуклюже, чтобы легко запросить, когда вам нужно что-то сделать с более эффективным. Сказав это, я видел ряд продуктов, которые делают это для пользовательских атрибутов. Примерами систем, использующих метод опциона 2, являются Agresso и Kalido.

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

Если вы делаете пакетное приложение, которое вы намерены настраивать для себя, у вас есть три широких подхода, которые вы можете предпринять.

  1. EAV структура, как вариант 2. Это гибкое, но неэффективно для запроса, в частности, как запросы становятся сложными с несколькими соединениями.

  2. Сделайте набор полей «Пользователь» (User1, User2 и т. Д.) На таблицах. Это ограничивает вас конечным числом, но это может быть довольно большим (вы можете иметь User01-User99, если хотите). Тем не менее, это самый эффективный и простой запрос. Другой - то, что поля несколько непрозрачны. Вы должны иметь доступ к информации о конфигурации, чтобы знать значение «User3». Он также жертвует некоторой безопасностью типа. Однако в балансе ваш пользовательский полевой механизм будет иметь некоторые свои собственные метаданные и общую структуру какого-то рода, поэтому через это можно обеспечить некоторую безопасность такого типа.

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

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

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

3

Любопытно, что вы не упоминаете ни о производительности, ни о целостности данных. Для того, что стоит, модель № 1 - лучший подход для этих соображений.

Гибкость значительно переоценивается применительно к моделям данных. Большинство структур таблиц хорошо известны в начале разработки и остаются стабильными на протяжении всей жизни базы данных. Если у вас есть приложение, в котором модель действительно жидкая и непознаваема, то, вероятно, вы не должны использовать РСУБД вообще. Вместо этого выберите один из продуктов NoSQL.

Так что это еще один голос за # 1.

+1

Поскольку производительность и целостность данных являются двумя наиболее важными элементами проектирования базы данных (безопасность является третьей), вы получаете +1 от меня. – HLGEM

1

@marc_s Я не верю, что «почти всегда» можно сделать любой выбор среди вышеперечисленных вариантов. Существует случай для поддержки обоих решений.

Вариант № 1 Идите для этого, когда объект X определен корректно, т. Е. Вы точно знаете, что вам нужно для захвата, чтобы определить X. В этом случае одна единственная запись X в значительной степени захватывает все экземпляры X означает.

Вариант № 2 Для этого необходимо, чтобы такой объект X не мог быть полностью определен, т. Е. Вы не знаете, какие атрибуты набора необходимы для его определения «полностью».

См., Например, возьмите пример записи сотрудника, как указано в статье «Пять простых ошибок в дизайне базы данных, которые следует избегать» [ссылка предоставлена ​​@marc_s]. Да!!! у вас возникнет соблазн получить вариант 1, но если вы рассмотрите случай сотрудников, работающих в крупных организациях, как только одна запись информации о сотруднике - как ее определение, так и контент являются очень динамичными и требуется комбинация опции №1 и опции №2.

+1

Я по-прежнему считаю, что в более чем 90% случаев я не вижу никакой веской причины для варианта № 2, учитывая все отрицательные свойства (целостность данных, производительность, неуклюжие запросы) ... если вам не нужна особый атрибут - сделать его нулевым. Если у вас есть блоки атрибутов для определенных сотрудников, но их в отдельной таблице, привязанной к FK, я еще не нашел действительно убедительной причины для EAV ... –

+0

Ответ на ваш комментарий в качестве следующего ответа. – shreeneewas

3

У каждого решения проблемы. # 1 будет хорошим подходом, если вы знаете колонки, которые вам нужны заранее. Однако в некоторых случаях столбцы не известны заранее. Например, пользовательские поля, которые пользователь добавляет к функциональности.

Сказав это, EAV имеют множество проблем. При правильном использовании ИМО они полезны.

  1. Убедитесь, что вы не создаете EAV для всего. Это только для «неизвестных предметов».
  2. Помните, что EAV не зависят от внешних ключей.
  3. Производительность низкая из-за нетривиальных запросов, а обслуживание может быть больше.
  4. Имейте в виду, что EAV необходимо поворачивать, чтобы сделать его значимым (ну, чаще всего).
0

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

1

@marc_s

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

Вот пример из финансового домена.

Если вы хотите захватить все атрибуты сделки, это зависит от его типа инструмента. Гораздо легче зафиксировать большинство инструментов Forex, Money Market и Bond, поскольку они очень структурированы. Но по мере продвижения к производным продуктам это становится очень громоздким. Они очень экзотичны по своей природе и продолжают меняться с точки зрения структуры (отсюда и ее значение и т. Д.). Чтобы зафиксировать такую ​​динамически меняющуюся информацию, мы должны выбрать EAV. Конечно, делая этот выбор, вы должны знать, что он приносит много негативов, перечисленных выше в ваших комментариях.

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

Shrini

Смежные вопросы