Должны ли черновые записи храниться в отдельной таблице? - PullRequest
4 голосов
/ 11 марта 2010

Мы создаем простую веб-систему, в которой кто-то добавляет запись, например, страницу CMS, которая утверждается ответственным лицом перед тем, как показываться на веб-сайте.

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

Мы думали о полном контроле версий, но полагаем, что мы можем упростить эту задачу, просто имея: 1. Только черновик, 2. Только живой или 3. Один черновой и один живой.

Эта функциональность требуется для нескольких «вещей», а не только для страниц.

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

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

Ответы [ 4 ]

8 голосов
/ 11 марта 2010

Перемещение материала из таблицы в таблицу при изменении состояния - плохая идея.

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

Это просто изменение состояния - для этого оптимизированы реляционные базы данных.

Одна таблица, несколько состояний - это стандартный подход.

Если вы обнаружите, что дела идут ужасно медленно - и вы можете доказать, что основанный на состоянии запрос является основной причиной - вы можете прибегнуть к «материализованным представлениям» или аналогичной технологии, в которой изменение состояния (и результирующее перемещение) обрабатывается СУБД.

Таблица для каждого состояния - плохая идея.

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

    Если состояние - это просто столбец, добавление новых состояний - это добавление новых значений и новых операторов if в коде. Изменения состояния - это просто обновления, а не «удаление-вставка».

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

  2. Вы не можете легко иметь подсостояния. Многие конечные автоматы на самом деле являются множественными вложенными конечными автоматами. Добавление подсостояния с таблицей за состоянием создает еще больше таблиц с еще большим количеством правил.

    Если состояние - это просто столбец, вложенное подсостояние - это просто еще один столбец с новыми операторами if в коде. Изменения состояния - это просто обновления, а не «удаление-вставка».

  3. Вы не можете легко иметь параллельные конечные автоматы. Много раз происходит много параллельных изменений кода состояния. Иногда существуют ручные рабочие процессы (утверждения) и автоматические рабочие процессы (архивирование, копирование в хранилище данных и т. Д.). В случае таблиц состояний и параллельных конечных автоматов невозможно рационально реализовать их

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

3 голосов
/ 11 марта 2010

Нет. Один тип сущности, одна таблица.

Причины пересмотреть:

  1. Количество записей в черновике превышает количество записей в реальном времени в тысячи раз.

  2. Условия безопасности требуют, чтобы некоторые пользователи, которые обращаются к базе данных напрямую, имели определенные права на черновые или живые записи на уровне GRANT / REVOKE, но не на другие типы записей.

Второй рассматриваемый дизайн - это одна таблица для Предметов и вторая таблица для LiveItems. Вторая таблица содержит только идентификаторы для активных элементов. Таким образом, вы сохраняете свой дизайн единой таблицы, но вы можете найти LiveItems, присоединив свою таблицу с одним столбцом обратно к основной таблице.

2 голосов
/ 11 марта 2010

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

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

У вас будет две модели:

class Post < ActiveRecord::Base
end

class Draft < Post
end

Любой черновой объект берется из таблицы сообщений.
Параметр Type делает его постом или черновиком.

Всякий раз, когда вы хотите опубликовать пост, вы должны сделать следующее:

@draft = Draft.first
@draft[:type] = 'Post'
0 голосов
/ 04 августа 2015

Я только что сделал драгоценный камень для такого случая использования. Черновики хранятся в отдельной таблице: https://github.com/ledermann/drafting

...