Нормализация базы данных - я думаю? - PullRequest
1 голос
/ 23 января 2012

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

Давайте возьмем два объекта в качестве примера: новость, которая будет размещена на веб-сайте, и продукт, который будетпродается на сайте.Оба из них имеют общие свойства:

  • Идентификаторы: идентификатор, идентификатор клиента, родительский идентификатор (длинный)
  • Флаги: удаленные, заархивированные, неактивные (логические)
  • Даты: созданы, изменены, удалены (дата / время)
  • Содержание: имя, описание

И, конечно, у них есть некоторые свойства, которые отличаются:

  • Новость: автор, дата публикации
  • Продукт: цена, налог

Итак (наконец) вот мой вопрос.Допустим, у нас есть 100 объектов в нашей системе, и все они следуют этой схеме.У них много перекрывающихся полей и несколько уникальных полей.С точки зрения реляционной базы данных, было бы лучше:

Вариант первый: меньше таблиц, общие таблицы

  • table_id: id, идентификатор клиента,родительский идентификатор (длинный) (идентификатор - это первичный ключ, идентификатор GUID для всех объектов)
  • table_flag: идентификатор, удаленный, заархивированный, неактивный (логический)
  • table_date: идентификатор, создан, изменен,удалено (datetime)
  • table_content: идентификатор, имя, описание
  • table_news: id, автор, дата публикации
  • table_product: id, цена, налог

Вариант второй: повторение дополнительных таблиц, общие поля

  • table_news: идентификатор, идентификатор клиента, идентификатор родителя, удален, заархивирован, неактивен, имя, описание, автор, публикациядата
  • table_product: идентификатор, идентификатор клиента, идентификатор родителя, удаленный, заархивированный, неактивный, имя, описание, цена, налог

Для полного раскрытия информации - я разработчик, а неDBA, и поэтому я предпочитаю первый вариант.Но есть другой член команды, который предпочитает второй вариант, и я думаю, что он зарабатывает действительные очки.

Вариант первый: за и против

  • Pro: заключает в капсулу общееполя в общие таблицы.
  • Pro: Нужно изменить общее поле?Измените его в одном месте.
  • Pro: создает новые поля / таблицы только тогда, когда они необходимы.
  • Pro: проще создавать запросы динамически, меньше повторяющегося кода
  • Con: Больше объединений для создания объектов (не уверен, что это повлияет на БД)
  • Con: Более сложные запросы для хранения объектов (не уверен, что это повлияет на БД)
  • Con: Общие таблицы станутОгромное время

Вариант второй: за и против

  • за: Возможно, лучше распределить нагрузку по всем объектам по таблицам?
  • Pro: может индексировать таблицу новостей по идентификатору клиента и индексировать таблицу продуктов по родительскому идентификатору.
  • Pro: более читабельно для человеческого глаза: легко увидеть все поля дляобъект в одной таблице.

Мои два цента

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

Извинения за затянутое времявопрос.Я не очень хорошо разбираюсь в DB lingo, так что, возможно, я бы суммировал это более кратко, если бы я лучше понимал такие термины, как нормализация.Я пытался найти ответы на эту тему, и хотя я нашел много близких (я подозреваю, что это обычная проблема с БД), я не смог найти ни одного ответа на все мои вопросы.Я прочитал эту статью о нормализации:

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

Спасибо

John

1 Ответ

2 голосов
/ 23 января 2012

Вы должны прочитать Шаблоны архитектуры корпоративных приложений . Автор Martin Fowler.Он пишет о нескольких вариантах описываемого вами сценария:

  • Наследование одной таблицы : одна таблица для всех подтипов объекта.Сохраняет все атрибуты, устанавливая их NULL там, где они неприменимы к подтипу объекта строки.

  • Наследование таблицы классов : одна таблица для столбца, общая для всех подтипов, затем однатаблица для каждого подтипа для хранения столбцов, специфичных для подтипа.

  • Наследование конкретной таблицы : одна таблица для каждого подтипа, в которой хранятся как столбцы, специфичные для подтипа, так и столбцы, общие для всехподтипы.

  • Сериализированный большой объект : одна таблица для всех подтипов объекта.Сохраняйте общие атрибуты как обычные столбцы, но объединяйте необязательные столбцы или столбцы, относящиеся к подтипу, как поля в BLOB-объекте, в котором хранится XML или JSON или любой другой формат.

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

Однако обратите внимание, я использую слово подтип выше.Я хотел бы использовать эти проекты, только если различные типы объектов являются подтипами общего базового класса.Я предполагаю, что News item и Product на самом деле не разделяют логический базовый класс (кроме Object);они не являются подтипами общего суперкласса.

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

...