Одна таблица на каждый подобный объект? - PullRequest
0 голосов
/ 04 августа 2009

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

У них есть следующие свойства:

магазин: X, Y, имя, ширина, высота, тип, адрес

место в корзине: X, Y, имя, ширина, длина, тип, вместимость

стойка: X, Y, имя, ширина, длина, тип, высота, баланс_предел

пекарня: X, Y, имя, ширина, длина, тип, open_hours

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

X, Y, ширина, высота, имя и тип. И что их отличает:

магазин: адрес

место для тележки: вместимость

стойка: balance_limit

пекарня: open_hours

Я знаю, что в будущем все эти типы объектов будут иметь свои собственные новые свойства и что они получат новые свойства, которые будут иметь все они сразу.

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

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

Итак, мой вопрос:

Должен ли я составить таблицу базы данных для каждого типа объекта (магазин, магазинная тележка, стеллаж, пекарня), потому что это будет более понятным, или мне следует объединить все это вместе в одну таблицу, поскольку у них одинаковый список свойств? *

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

Ответы [ 6 ]

1 голос
/ 04 августа 2009

Что я предлагаю:

  1. Правильно спроектируйте модель домена , без каких-либо проблем с базой данных. Объекты, совместно использующие свойство (например, name ), не означают, что они каким-либо образом связаны. Хотя они вполне могут быть ...
  2. Сопоставьте этот дизайн со структурой базы данных, выбрав хорошо известные Объектно-реляционные структурные шаблоны (ср. Дизайн базы данных ).
  3. Разработайте ваш продукт, используя подходящее решение ORM (предпочтительно такое, которое позволяет впоследствии изменять базовую структуру базы данных).
  4. В случае, если у вас возникнут проблемы с производительностью, рассмотрите (де) нормализацию вашей базы данных для решения проблемы.
1 голос
/ 04 августа 2009

Это непростой вопрос ... Базы данных SQL плохо умеют моделировать иерархии классов.

Вам понадобится хороший ORM.

То, что я положил в таблицу иерархии классов, сделайте так:

Сначала я убедился, что это уместно: например, размещение узлов, статей и т. Д. Для веб-CMS в одной таблице имеет смысл, потому что это все варианты одного и того же.

Идея состоит в том, что вам нужно создавать столбцы базы данных для поиска, индексации и выполнения запросов SQL, но вам не нужно хранить всю вашу информацию в столбце базы данных. Остальное можно сохранить в сериализованном объекте в столбце BLOB.

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

Обычно, когда я сохраняю объект в базе данных, соответствующие столбцы в соответствии с его классом заполняются, а остальные данные (или даже весь объект) помещаются в BLOB.

Самое замечательное в этом то, что если вы добавляете значение члена, которое не нужно искать или индексировать, только хранить, вам не нужно помещать его в столбец базы данных, поэтому вы не вносите никаких изменений в База данных вообще: она будет храниться в сериализованном BLOB. Единственное, что нужно сделать, это добавить значение по умолчанию для этого члена в коде десериализации, чтобы объекты этого класса, которые уже находятся в базе данных и не имеют этого члена, будут иметь приличное значение по умолчанию для него.

Вы также можете создавать версии своих форматов объектов, если хотите, они становятся более сложными.

Однако эта схема имеет некоторые недостатки:

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

Например, вы, вероятно, захотите поместить адреса в отдельную таблицу и добавить соответствующие поля (почтовый индекс, страну, улицу, номер и т. Д.): Размещение всего этого в вашей основной таблице добавит слишком много столбцов. Кроме того, в какой-то момент вы захотите добавить некоторых клиентов или другие вещи, которые находятся в другой таблице и также имеют адрес, поэтому лучше поместить адрес в отдельную таблицу и ссылаться на них.

То же самое для людей или компаний и т. Д.

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

Это может стать немного волосатым.

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


Теперь есть другие решения:

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

Тогда вы получаете 1 стол на класс.

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


Как выбрать между двумя?

В основном, если вы создаете веб-CMS и сохраняете в таблице объекты класса, производные от Node, такие как: - Статья - изображение с легендой - Галерея - и т. д.

Все эти объекты в основном одинаковые вещи. Все они будут иметь заголовок, поле TextContent, принадлежат ParentNode и т. Д.

Если вы выполняете поиск по ключевому слову «foo» в TextContent, гораздо проще, если все объекты находятся в одной таблице.

Если вы хотите перечислить все дочерние элементы ParentNode для отображения их на веб-странице, также будет намного проще, если все будет в 1 таблице.

Так что в этом случае первый метод действительно выгоден.

Теперь в вашем случае объекты не так похожи.

Лично я бы даже не дал им тот же базовый класс. Я бы создал Mixin с именами «ThingWithCoordinates» (может быть, что-то более короткое) и добавил бы это к классам.

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

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

Наиболее важным является то, что ваша иерархия классов (и, следовательно, таблицы) должна основываться на чем-то СООТВЕТСТВУЮЩИХ (автодилеры и пекарни являются магазинами), а не на общих чертах, которые существуют между объектами, которые на самом деле не имеют ничего общего (например, корзина и магазин). Для этого есть миксины для общего кода, но не базовые классы.

0 голосов
/ 04 августа 2009

Если общность похожа на shop_size, я бы предложил создать для этого отдельную таблицу.

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

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

В основном вы получаете гибкость, ИМО.

0 голосов
/ 04 августа 2009

Поиск в Интернете по теме «Обобщение специализации реляционного моделирования».

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

0 голосов
/ 04 августа 2009

Какую пользу вы получаете от «общего доступа» к таблице общих предметов?

Если их нет, не делайте этого - просто вставьте их в разные таблицы (особенно, если они в будущем будут расходиться).

Я полагаю, вы не используете ORM?

0 голосов
/ 04 августа 2009

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

Кроме того, каждый объект затем выделяется с точки зрения развития и сложности.

...