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

StackOverflow https://stackoverflow.com/questions/103766

  •  01-07-2019
  •  | 
  •  

Вопрос

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

Я думал о нескольких способах, но не могу понять, какой самый лучший.Это очень маленькое веб-приложение.Одним из способов было бы создать таблицу PendingChanges, которая имитирует схему другой таблицы, а затем, как только изменение будет одобрено, я мог бы обновить реальную таблицу информацией.Другим подходом было бы выполнить какое-то управление версиями записей, при котором я сохраняю несколько версий данных в таблице, а затем всегда извлекаю запись с наибольшим номером версии, которая была помечена как одобренная.Это ограничило бы количество дополнительных таблиц (мне нужно сделать это для нескольких таблиц), но потребовало бы от меня дополнительной обработки каждый раз, когда я извлекаю набор записей, чтобы убедиться, что я получаю правильные.

Есть какой-нибудь личный опыт использования этих или других методов, который мог бы оказаться полезным?

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

Кто-нибудь пробовал приведенное ниже решение, в котором вы сохраняете ожидающие изменения из любой таблицы, которая должна отслеживать их как XML, в специальной таблице PendingChanges?Каждая запись будет содержать столбец, в котором указано, для какой таблицы были внесены изменения, столбец, в котором, возможно, хранится идентификатор записи, которая будет изменена (null, если это новая запись), столбец datetime для сохранения, когда было внесено изменение, и столбец для хранения xml измененной записи (возможно, это может сериализовать мой объект данных).Поскольку мне не нужна история, после утверждения изменения реальная таблица будет обновлена, а запись PendingChange может быть удалена.

Есть какие-нибудь мысли по поводу этого метода?

Это было полезно?

Решение

Размер - ваш враг.Если вы имеете дело с большим количеством данных и большим количеством строк, то смешивание исторических данных с текущими приведет к тому, что вы забьете себе голову.У вас также возникнут проблемы, если вы присоединитесь к другим данным, убедившись, что у вас есть правильные строки.

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

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

Другие советы

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

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

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

  1. Главный стол A
  2. Другая таблица B, в которой хранится измененная запись (и поэтому она в точности похожа на первую) + 2 дополнительных столбца (FKey для C и код, указывающий вид изменения)
  3. Третья таблица C, в которой хранятся все такие записи, требующие утверждения
  4. Четвертая таблица D, в которой хранится история (вам, вероятно, это не нужно).

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

Учитывая движение за соблюдение требований SOx, которое было брошено в лицо большинству публичных компаний, у меня был немалый опыт в этой области.Обычно я использую отдельную таблицу с отметкой времени ожидания изменений с каким-нибудь столбцом флага.Лицо, ответственное за администрирование этих данных, получает список ожидающих изменений и может принять или не принять решение.Когда часть данных принимается, я использую триггеры для интеграции новых данных в таблицу.Хотя некоторым людям не нравится метод триггера, и они предпочли бы закодировать это в сохраненных процедурах.У меня это хорошо работало, даже в довольно больших базах данных.С этой сложностью может быть немного сложно справиться, особенно при работе с ситуацией, когда одно изменение напрямую конфликтует с другим изменением, и в каком порядке обрабатывать эти изменения.Таблицу, содержащую данные запроса, никогда нельзя будет удалить, поскольку в ней хранятся, так сказать, "хлебные крошки", которые потребуются на случай, если возникнет необходимость отследить, что произошло в конкретной ситуации.Но при любом подходе необходимо оценить риски, подобные тому, что я упомянул в связи с конфликтующими данными, и должен быть создан уровень бизнес-логики для определения процесса в таких ситуациях.

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

Я бы создал таблицу с флагом an и создал представление типа

 CREATE OR REPLACE VIEW AS 

  SELECT * FROM my_table where approved = 1

Это может помочь разделить зависимости между aprovement и запросами.Но, возможно, это не самая лучшая идея, если нужно внести обновления в представление.

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

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

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

Еще одна идея состояла бы в том, чтобы иметь три таблицы.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top