Разработка архива в базе данных. Некоторые шаблоны, возможно?

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

Теперь я предложил, чтобы мы просто добавили еще один дополнительный столбец, названный "состоянием", которое имело бы несколько допустимых значений: АКТИВНЫЙ и УДАЛЕННЫЙ. Таким образом, мы можем различать нормальные (активные) и удаленные события и создать действительно простые запросы (ВЫБОР * ОТ СОБЫТИЙ ГДЕ СОСТОЯНИЕ = 'АКТИВНЫЙ'). Мой коллега однако не согласился. Он указал, что независимо от того, что прямо сейчас активные события и удалил события, делятся той же информацией (таким образом, они могут быть сохранены в той же таблице) в будущие требования, мое изменение и клиент, например, должны будут хранить некоторую дополнительную информацию об удаленном Событии (как дата удаления, кто удалил его, почему он сделал это - вид комментария). Он сказал, что для выполнения тех требований в будущем мы должны будем добавить дополнительные столбцы в таблице EVENTS, которая содержала бы данные, специфичные для удаленных Событий а не для активных событий. Он предложил решение, где дополнительная таблица составлена (как DELETED_EVENTS) с той же схемой как таблица EVENTS. Каждое удаленное событие было бы физическое удаленный из таблицы EVENTS и было бы перемещено в таблицу DELETED_EVENTS.

Я был категорически не согласен с его идеей. Мало того, что это сделало бы SQL-запрос более сложным и менее эффективным, но также и это полностью против YAGNI. Я также не согласился с ним, что моя идея будет, сделал нас для создания дополнительный (не nullable) столбцы в таблице EVENTS, если требования, измененные в будущем. В моем сценарии я просто составил бы новую таблицу как DELETED_EVENTS_DATA (который будет содержать дополнительных, данные архива), и добавил бы, что ссылка вводит таблицу EVENTS для поддержания связи "один к одному" между таблицами EVETNS и DELETED_EVENTS_DATA.

Тем не менее, я боролся тем, что два разработчика, которые обычно разделяют подобные взгляды на разработку программного обеспечения и проектирование баз данных, могли иметь так радикально различные мнения о том, как это требования должно быть разработано на уровне базы данных. Я думал, что мы, возможно, и вход в неправильное направление и существуем другое (третье) решение? Или есть ли больше затем всего одна альтернатива? Как Вы разрабатываете этот вид требований? Есть ли какие-либо шаблоны или инструкции по тому, как сделать это правильно? Любая справка будет глубоко цениться

9
задан Patrick Karcher 22 January 2010 в 01:04
поделиться

7 ответов

Хорошо, как мы обрабатываем это следующим образом.

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

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

Event
EventId   EventName   ...   Deleted
1         Dinner            0
2         Supper            1
3         Lunch             0
4         Lunch             1

Audit
AuditId    EntityTypeId     EntityId    ActionTypeId    ActionDateTime   ... etc 
1          1 (Event)        2 (EventId) 1 (Deleted)     2/1/2010 12:00:00
1          1 (Event)        4 (EventId) 1 (Deleted)     3/1/2010 12:00:00

Теперь, если у вас есть другие объекты, которые вы хотите захватить (например, местоположение - где Расположение - это таблица), а это будет выглядеть так ...

Audit
AuditId    EntityTypeId     EntityId    ActionTypeId    ActionDateTime   ... etc 
1          1 (Event)        2 (EventId) 1 (Deleted)     1/1/2010 12:00:00
1          1 (Event)        4 (EventId) 1 (Deleted)     2/1/2010 12:00:00
1          2 (Event)        2 (LocationId) 1 (Deleted)     3/1/2010 12:00:00
1          2 (Event)        8 (LocationId) 1 (Deleted)     4/1/2010 12:00:00
1          2 (Event)        9 (LocationId) 1 (Deleted)     5/1/2010 12:00:00

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

SELECT  *
FROM    Event E
        INNER JOIN Audit A
            ON E.EventId = A.EntityId 
WHERE   E.Deleted = 1
        AND A.EntityTypeId = 1 -- Where 1 stands for events

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

Надеюсь, что это поможет

Редактировать:

Кроме того, если у нас есть сильные требования к аудиту, мы выполняем следующее ... Ни один из вышеперечисленных изменений, но мы создаем вторую базу данных, называемую «xyz_audit», которая захватывает до и опубликовать каждое действие, которое происходит в базе данных. Эта вторая база данных имеет одну и ту же схему, что и первая база данных (без таблицы аудита), за исключением того, что каждая таблица имеет 2 дополнительных столбца.

Первая дополнительная колонна представляет собой prepostflag, а второй столбец - это аудитид. Следовательно, первичный ключ теперь проходит через 3 столбца, «xyzid», «PrepostFlag» и «AuditID».

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

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

0
ответ дан 4 December 2019 в 23:39
поделиться

Не используйте столбец состояния.

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

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

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

4
ответ дан 4 December 2019 в 23:39
поделиться

Часто вызов суда в таких ситуациях. Не зная большего, чем вы сказали мне, я бы склонен идти с вашим решением, что это просто имеет виртуальное удаление. Я считаю, что ваше применение Ягни хорошо. Если пользователь в будущем дает требования к этапам регистрации в событиях . Это особенно верно, если логика для борьбы с событиями в БД хорошо инкапсулирована (легко изменить позже).

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

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

0
ответ дан 4 December 2019 в 23:39
поделиться

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

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

Если у вас есть аудита, вы уже знаете, кто отметил запись как удаление и когда.

Если нет, вы должны добавить эти поля к вашей таблице.

Периодически я могу удалить удаленные записи в таблицу архивирования, чтобы вызвать производительность запросов на главной таблице. Скажем, переместите все удаленные записи, которые были удалены более 6 месяцев. Затем имейте вид Anothe, который сочетает в себе обычную таблицу и таблицу архивирования для администраторов для запроса.

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

0
ответ дан 4 December 2019 в 23:39
поделиться

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

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

0
ответ дан 4 December 2019 в 23:39
поделиться

Просто остановите сервис, замените EXE и перезапустите его. Это, вероятно, должно быть частью вашего установщика. Разделяя его на отдельные сборки, только ради переусадки - это кроличье отверстие.

-121--3579269-

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

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

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

2
ответ дан 4 December 2019 в 23:39
поделиться

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

0
ответ дан 4 December 2019 в 23:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: