Как лучше настроить базу данных для приложения? Нормализованный против реального мира - PullRequest
3 голосов
/ 24 февраля 2011

Рассмотрите, пожалуйста, эту настройку для приложения, поддерживаемого базой данных. (в моем случае БД - это MySQL, а приложение - в Ruby (Rails 3), но я не думаю, что это имеет значение для этого вопроса)

Допустим, у меня есть приложение для склада.

У меня есть несколько предметов, которые будут иметь категории и статусы.

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

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

1011 * Etc. *

Вот вопрос:

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

Тогда я буду хранить все категории в этой таблице, и любая категория определенного типа, например все категории деталей, будет иметь внешний ключ для category_type - parts и т. Д. То же самое для типов.

Это нормализованный способ.

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

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

Спасибо.

Ответы [ 2 ]

4 голосов
/ 24 февраля 2011

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

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

Имейте в виду, что другой подход заключается в том, чтобы вообще не создавать таблицы статусов и категорий, а сохранять значения статуса и категории в исходных таблицах. Вы можете сделать это с помощью enumerable (ENUM) в MySQL или в Rails. В MySQL ENUM хранится в базе данных как целое число, но разрешается в значение слова, например «обработано», «отправлено» или «отменено». Преимущество этого состоит в том, что если ваши статусы не меняются часто, у вас есть на одно объединение меньше, и вам легче читать базу данных и модель Ruby. В Ruby ENUM может быть просто списком констант, которые имеют ключ (целое число) и значение (строку), связанные с ними. Вы можете использовать целочисленное значение для запроса и обновления базы данных, а также значение слова на стороне вашего приложения.

Я полагаю, что оба подхода законны, путь, который вы выберете, зависит от ваших потребностей. Если вы настроены на сохранение данных в базе данных, проанализируйте, как вы будете взаимодействовать со статусами и категориями - ваш подход может отличаться. Какой подход будет быстрее и проще запрашивать? Какой из них будет легче обновить или изменить? Как часто вы читаете; как часто ты пишешь? Наконец, имейте в виду, что вы Agile! Любой подход может быть преобразован в другой с помощью простой миграции и некоторого рефакторинга. Подход, который является самым простым для вашего приложения сейчас, может оказаться не лучшим в будущем, и это совершенно нормально. Вот что так здорово быть проворным!

2 голосов
/ 24 февраля 2011

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

С реляционной точки зрения ни один из подходов - помещение всех перечислений статуса в одну таблицу или разбиение их на отдельные таблицы - не более "нормализован", чем другой. Но с теоретико-типовой точки зрения имеет смысл поместить part_categories и vendor_categories в их собственные отдельные таблицы, ни по какой другой причине, кроме случаев, когда в модели не требуется кода, чтобы убедиться, что вы случайно не связали категорию поставщика с деталью. ,

Если вы все-таки поместите их в одну таблицу, в Rails есть хорошая функция, называемая полиморфными ассоциациями, которая автоматизирует тип и столбцы id для вас. Это разумный компромисс между двумя подходами.

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

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