2015-08-06 2 views
2

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

Модель, называемая mpb_item, имеет таблицу mpb_items.

Внутри этой таблицы пунктов есть столбцы, такие как:

role1_start_date, role2_start_date, role3_start_date, role4_start_date 

Не идеально, но это то, что она есть. Думаю, они должны были быть в отдельном ролевом столе.

Мне нужно добавить функциональность, чтобы приостановить любую из этих ролей (или все из них).

Я предполагаю, что я могу либо:

  1. К существующей таблице, я могу добавить новый столбец булева для каждого существующего столбца роли. например role1_suspended, role2_suspended и т.д.

  2. Создать таблицу с именем mpb_suspensions, с 2-мя колонками: mpb_item_id и role_name. Поскольку роли не имеют самих идентификаторов, столбец role_name будет хранить «role1» или «role2» и т. Д. В зависимости от того, какая роль была приостановлена.

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

+0

Можете ли вы опубликовать модель и ее ассоциации? Что вы подразумеваете под дизайном? Вам нужен RDB с Rails (SQLite3, MySQL, PostgreSQL, с последним самым мощным с большим количеством данных). Когда вы говорите, что наследуете, вы имеете в виду, что вы используете устаревший код или чужой проект? – onebree

+0

По какой-либо причине вы не можете создать подходящую модель ролей (hah) и перенести данные из таблицы «mpb_item» внутри миграции? –

+0

кто-то elses проект его около года или около того. Я не уверен, можно ли вытащить данные из mpb_item, так как тогда будет генерировать новую строку для каждой роли, как это будет работать? Хорошо бы написать «mpb_item.role.suspend». Я не могу отправить код в ту минуту, пока я дома, только сейчас ... – user3437721

ответ

0

Если бы мне пришлось строить это, учитывая минимальную информацию, которую вы предоставили, я бы начал с выбора варианта 2, который вы описали. (А RoleSuspension своя таблица) Преимущества: всего

  • меньше новых столбцов, а не делать какие-либо таблицы неопределенно большого
  • нет избыточных столбцов (role1, роль2 и т.д.)
  • нет необходимости для добавления большего количества столбцов, если число возможных ролей изменяется (то есть более нормализовано)
  • no nil values ​​(approach 1)
  • Вы можете легко запросить общее состояние RoleSuspensions (тогда как с подходом 1 вам понадобится для подсчета значений non-nil в role1_suspended, role2_suspended и т. д., затем суммируйте их) и ea sier к индексу
  • вы можете прикрепить логику к RoleSuspension; это отдельное животное из его родительского MbpItem. Если это всего лишь куча логических столбцов, любая сложная логика должна быть собрана в модель MbpItem и, вероятно, будет намного более беспощадной для поддержания.

Следуя логике, вариант 2, в подвешивания роль будет включать в себя создание новой записи, как это:

@mbp_item.role_suspensions.create!(role_number: 2) 

и проверка состояния подвески будет включать в себя что-то вроде этого: производительность

if @mbp_item.role_suspensions.any? 
# or.... 
RoleSuspension.where(role_number: 3).each do |s| 
    puts "Item #{s.mbp_item} is suspended for role #{s.role_number}." 
end 

базы данных будет больше учитывать этот подход в зависимости от ответов на следующие вопросы:

  • Где и как часто вам нужно проверять наличие приостановки роли?
  • Когда вы проверяете наличие приостановки роли, как вы можете задать вопрос? Другими словами, есть какая-то глобальная задача: «Какие существуют приостановки роли и для каких mbp_items?» или вы проверяете наличие приостановки в заданном mbp_item при рендеринге этого объекта?

Если вам необходимо проверить роль суспензии очень часто, возможно, вы должны добавить булеву столбец mbp_itemshas_suspensions под названием, которая будет частично кэшем в том, что он будет указывать, существует ли какая-либо суспензия для этого MbpItem (и должны поддерживаться в after_create и after_destroy крючках).

С другой стороны, если вы знаете, что подвеска информация никогда не нужно будет иметь свою собственную логику и не нужно будет запрашиваться непосредственно, вы можете добавить одного столбец MbpItem, role_suspensions, содержащий сериализованная массив целых чисел для приостановленных ролей. Это будет гораздо менее инвазивным подходом с точки зрения структуры базы данных и, вероятно, намного проще, чем ваш вариант 1, поскольку он позволит вам приостановить и отменить приостановление любого номера роли с меньшим количеством кода и меньше метапрограммирования, но если вам когда-нибудь понадобится добавить любую причудливую логику в процесс приостановки или десуспензии (т. е. если RoleSuspension заслуживает статуса как своего собственного объекта), вы бы пожалели об этом.

+0

Отличный ответ. Мы проверим подвески на данном MpbItem, это будет не очень регулярно. Когда пользователь загружает MpbItem, на экране просмотра отображается каждая роль, и если она приостановлена ​​или нет. В твоем создании! код, где хранятся номера ролей? Мы не храним идентификаторы в настоящее время, можем использовать константы? – user3437721

+0

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

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