|
|
|
Удаление и архивирование данных
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. С недавнего времени меня заинтересовал вопрос об удалении и архивировании данных. Сейчас поясню, что я имею ввиду. На практике часто встречается подобная ситуация: Необходимо "логически" удалять объекты системы (записи из таблиц). Это значит, что их нельзя удалить насовсем. Нужно просто пометить в каком-нибудь поле таблицы, переместить в другую таблицу, использовать аудит и т.п. Зачастую подобная задача возникает в таком контексте: нужно удалить запись из таблицы; если зависимых данных нет (в других таблицах по внешнему ключу, к примеру), то тогда удалить запись "физически"; а если же есть - то "логически". Предположим удаление должна выполнить ХП. Ситуация: если можно - "физически", иначе - "логически". Тут хотелось бы узнать мнение экспертов (идея, производительность, подводные камни и т.п.), как реализовать такое поведение. 1. Пробовать удалить запись сразу. Если возникла ошибка констрейнта, то удалять логически. 2. Сделать проверку на существование зависимых данных дополнительными селектами, если они есть, то удалять логически. Вторая ситуация - это само логическое удаление. 1. Использовать поле таблицы типа Status с возможными значениями, к примеру, A - active и D - deleted. В этом случае хотелось бы дополнительно узнать, есть ли смысл использовать представления на соответствующих таблицах, которые содержат Status='A', ибо обычно работа идет только с активными объектами, а удаленные нужны в основном только для статистики. 2. Использовать подкопию струкруты базы данных, чтобы все удаленное перекидывать туда. В этом случае, как я вижу, сильно успожнятся статистические запросы, которым нужны все записи. Появится куча юнионов и т.п. 3. Реализовать некую систему аудита, в которой будут сохранены удаленные данные, необходимые для будущих статистических запросов. В этом случае непонятно, как вообще создать подобную универсальную структуру, которая бы сохранила зависимые данные. Неговоря уж о сложности запросов. Третья ситуация - каскадное логическое удаление. Предположим есть зависимость таблиц: A -> B -> C. Как при логическом удалении записи из A, сразу удалить все зависимые в B и С? Опять же, при удалении записи из A, лучше сделать выборку зависимых данных в B и делать их логическое удаление или лучше повесить триггер на обновление (в случае использования поля Status) Status из A в D ? В целом, интуиция подсказывает, что меньше геморроя можно получить в случае с полем Status. Однако тут серьезный недостаток, как я вижу: с ростом количества записей, записи со Status = 'D' будут только тормозить работу. Также хотелось бы спросить мнение народа об использовании индексов в этих случаях (на поле Status, на таблицах-копиях для архивации и т.п.). Я пытался использовать каждый из описываемых методов, но всякий их них приводит к какому-нибудь тупику, задаче, которую трудно раскрутить. Особенно когда проект уже работает длительное время. Могу предположить, что кто-то сталкивался с чем-нибудь более изощренным. Резалтом этого топика хотелось бы иметь набор инструкций, как на этапе проектирования базы выбрать нужную методику. Надеюсь он прояснит ситуацию не только мне, но и поможет начинающим DBA. Заранее спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2006, 21:14 |
|
||
|
Удаление и архивирование данных
|
|||
|---|---|---|---|
|
#18+
1. Используйте общего предка для всех сущностей БД (системный объект). Так вам удастся обеспечить уникальность ПК в рамках всей базы и использовать "родную" ссылочную целостность для прозрачного контроля над связями. Впрочем, необходимость общего предка зависит от способа реализации наследования в БД, а уникальность ПК в рамках всей БД достижимо использованием GUID-а. Может существовать смешанная модель наследования. Например, для ряда случаев на связях 1-к-1, для других случаев, так называемая схема "inherite all attribute" (дублирование атрибутов в потомках). 2. Создайте таблицу связей Object-To-Object, где будет хранится информация о ссылках подчиненных объектов на родительские (или другие типы связей). Так вам удастся прозрачно и универсально получить весь граф объектов, например, при необходимости каскадного удаления. Впринципе, таблица связей не обязательна, но тогда вам придется для каждой сущности писать индивидуальный алгоритм получения графа. Таблица ObjectToObject - удобство использования, но падающая с ростом данных произодительность и необходимость некоторых действий по администрированию и ее оптимизации. Индивидуальный алгоритм - наоборот - увеличивающиеся затраты на разработку, но более высокая производительность и меньшие затраты на администрирование и поддержку. 3. Используйте две операции/две хп для удаления -логическое удаление(MarkAsDelete) -физическое удаление(Delete) с дополнительным bool-параметром (deleteCascade) При deleteCascade=true получаете и удаляете весь граф объектов. При deleteCascade=false проверяете, ссылаются ли другие объекты на удаляемый. Да - генерируете исключение и откатываете транзакцию. Различным ролям вы можете назначить привилегии MarkAsDelete, Delete, DeleteCascade. Наример, запретить группе пользователей физическое удаление (Delete) и разрешить MarkAsDelete. 4. С архивированием данных определитесь какой род информации необходимо архивировать. Часто ограничиваются архивированием(отсечением) истории. Способы архивации могут быть различными (поищите по форуму, обсуждалось): архивные таблицы, архивная база ... 5. Способы оптимизации: индексы само собой :), partitioned view/table, выделение проблемных таблиц и индексов в другие tablespace/file groups, при необходимости, изменение реализации наследования для проблемных сущностей на этапе эксплуатации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.12.2006, 12:12 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=34174252&tid=1544856]: |
0ms |
get settings: |
11ms |
get forum list: |
22ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
191ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
53ms |
get tp. blocked users: |
2ms |
| others: | 237ms |
| total: | 539ms |

| 0 / 0 |
