powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Логическое удаление записей
25 сообщений из 81, страница 1 из 4
Логическое удаление записей
    #33621738
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотелось бы узнать мнение на тему, кто как организует логическое удаление записей в БД (когда они удаляются на уровне пользователей, но физически продолжают присутствовать в БД) и какие в связи с этим преимущества и недостатки. Сейчас я вижу 2 варианта:
1. Пометка записи на удаление, т.е. введение поля статуса записи.
2. Введение в схему БД дополнительных таблиц для удаленных записей со структурой, совпадающей с оригинальной и перенос туда записей при удалении.
По 1-му подходу я вижу следующие недостатки: некоторое увеличение времени запросов к данным, т.к. приходится отфильтровывать "удаленные" записи, а также усложнение в случае наличия уникальных ключей, когда значение ключа занимается удаленной записью и не может быть использовано в актуальной, т.е. ключ надо расширять на 2 поля.
По 2-му подходу недостаток - в усложнении структуры данных и усложнении операции логического удаления (нужно помнить, что если у записи есть ссылки в дочерних таблицах, то их тоже нужно переносить в соответствующие зеркальные таблицы удаленных записей).
Кто поделится мыслями или опытом по данной проблеме?
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33621875
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При наличии статусного поля время можно сделать практически неизменным с помощью партиционирования. Хотя не факт, что стоит так делать - имхо это зависит в первую очередь от ожидаемой пропорции актуальных и удаленных записей. Делая партиционирование по статусу, мы ускоряем select за счет торможения delete-а.

Второй вариант - максимум, можно рассматривать как решение там, где нет партиционирования. Хотя все равно некрасиво.

Логику работы с дочерними записями в любом случае придется тщательно прописывать. Даже при простановке статуса он же должен быть каскадно проставлен зависимым записям итп.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33622553
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerДаже при простановке статуса он же должен быть каскадно проставлен зависимым записям итп
Ну как вариант не ставить статус для зависимых, а действовать в зависимости от статуса главной записи - например написать соответствующие view.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33622563
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_spy_ softwarerДаже при простановке статуса он же должен быть каскадно проставлен зависимым записям итп
Ну как вариант не ставить статус для зависимых, а действовать в зависимости от статуса главной записи - например написать соответствующие view.
Такой вариант у нас часто используется, единственная проблема не забывать делать проверку везде, где обрабатывается перечень.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33622584
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EstetsТакой вариант у нас часто используется, единственная проблема не забывать делать проверку везде, где обрабатывается перечень.
Ну как раз если организовать все запросы через фильтрующее представление, то эта проблема обходится
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33622854
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_spy_Ну как вариант
Обратите внимание на основную фразу: логику обработки зависимостей в любом случае придется тщательно прописывать. Как именно - отдельный обсуждаемый вопрос.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33622890
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerОбратите внимание на основную фразу: логику обработки зависимостей в любом случае придется тщательно прописывать. Как именно - отдельный обсуждаемый вопрос.
Согласен, поэтому в том моем посте я цитировал только вашу фразу насчет реализации этой логики
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33623849
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А зачем хранить "удаленные" записи? Если хранить их без взаимосвязей, то разобраться в них будет просто невозможно. Если со связями, то вполне могут возникнуть взаимные коллизии.
ИМХО.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33623912
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Удаленные данные хранятся для анализа и статистики (а также на случай возможного восстановления). Т.е. они могут быть недоступны обычным пользователям, которые будут считать, что данные удалены, но доступны привилегированным пользователям, которые смогут видеть всю историю и строить статистические отчеты.
В том-то и дело, что при логическом удалении должны сохраняться все взаимосвязи.
Хотелось бы услышать попдробнее насчет возможных взаимных коллизий.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33623973
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_spy_Хотелось бы услышать попдробнее насчет возможных взаимных коллизий.
Была группа товара "Автомобили". Удалили все товары этой группы, а саму группу переименовали в "Лифчики". Можно так? Почему нет? Вот и увидит превилигированный пользователь в "Лифчиках" "ВАЗ-2110". Оно надо? А если подобная практика достаточно часта, то он там и "Гематоген" может увидеть и "черта лысого". Разбираться заморишся.
И это самая простая (одноступенчатая) коллизия.

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

Мусор надо выкидывать, ИМХО.

А восстанавливать нужно из бэкапов, которые делать регулярно автоматом.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33624022
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторБыла группа товара "Автомобили". Удалили все товары этой группы, а саму группу переименовали в "Лифчики". Можно так? Почему нет? Вот и увидит превилигированный пользователь в "Лифчиках" "ВАЗ-2110". Оно надо? А если подобная практика достаточно часта, то он там и "Гематоген" может увидеть и "черта лысого". Разбираться заморишся.
Ну это все решается на уровне бизнес-логики приложения. Переименовать можно и при наличии записей в группе, тогда ВАЗ в "Лифчиках" увидят все пользователи. А можно сделать так, что при удалении всех записей в группе автоматом удаляется и сама группа. Подразумевается все ж таки, что семантика групп не меняется, если говорить только о коллизиях такого рода.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33624051
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_spy_Ну это все решается на уровне бизнес-логики приложения.
Если есть охота решать - решай. Только по объему это "решание" возможно будет сопоставимо с основным функционалом. Я бы все таки посоветовал честно ответить самому себе на вопрос - так ли нужны "анализ и статистика" по удаленным (читай ненужным) данным. Если действительно нужны - то желаю удачи.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33625357
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ненужных данных в системе практически не бывает. Зато идиотов-пользователей - сколько угодно и еще больше. И как человек, который некоторое время регулярно разбирался с тем, что пользователи натворили в базе, могу сказать: любого прога, который попробует безвозвратно удалять любую запись, успевшую поучаствовать в бизнес-процессах, нужно срочно и серьезно лечить.

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

Я в принципе допускаю, что данный конкретный случай был провокацией на тему "не прибьет ли эта девочка этого пользователя". Вот только таких не один и не два. Их почти за каждым десктопом.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33625422
Фотография vadiminfo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_spy_Ну как вариант не ставить статус для зависимых, а действовать в зависимости от статуса главной записи - например написать соответствующие view.
Т.е. тада надо будет написать запросы на соединение даже если главная табла не нужна? А када нужна - тада для этих табл другие view, чтобы избежать этих соединений? А када удаление из дочерних таблов то все то же?


Практика первого варианта есть в старом досовом клиппере. Там все что удалено помечается.

Второй вариант похож на аудит (скорее всего триггерный). Ить тада можно еще записывать и кто и что не тока удалил, но и изменил. Я такое делал. Но там были просто "особые" данные изменение которых китайцы считали серьезным преступлением. Но всю БД так аудить накладновато будет.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33625811
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vadiminfoТ.е. тада надо будет написать запросы на соединение даже если главная табла не нужна? А када нужна - тада для этих табл другие view, чтобы избежать этих соединений? А када удаление из дочерних таблов то все то же?
Да, все же вариант с каскадной простановкой статусов при логическом удалении главной записи видится более предпочтительным.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33629650
softwarerПри наличии статусного поля время можно сделать практически неизменным с помощью партиционирования. Хотя не факт, что стоит так делать - имхо это зависит в первую очередь от ожидаемой пропорции актуальных и удаленных записей. Делая партиционирование по статусу, мы ускоряем select за счет торможения delete-а.
Как-то я реализовавыл этот вариант. Остался тестовый код, может кому пригодится:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
--create sequence sdel
--/

drop view ttable
/
drop table ttable$
/

--таблица, хранящая как "живые", так и "мертвые" данные
create table ttable$(
    table_id number,
    descr varchar2( 255 ),
    dead$ timestamp, --number,   --индикатор смерти. Во многиз случаях можно (и лучше) использовать тип timestamp
--уникальные ключи можно создавать так
constraint pk_ttable$ unique(table_id, dead$)
using index
local
tablespace indx
--если не требуется управлять (большинство случаев), то можно
--иметь и такие PK.
--Но при большом количестве "мертвых" данных будет деградировать
--производительность. Поэтому вариант, предложенный выше, лучше.
--constraint pk_ttable$ primary key(table_id)
)
partition by list(dead$)(
    --раздел живых данных
    partition life
    values(null)    --dead$ is null
    --tablespace one
    ,
    --раздел смерти
    partition death
    values(default) --dead$ is not null
    storage(buffer_pool recycle)    --меньший приоритет в кеше
    --tablespace other
)
enable row movement --чтобы при попытке удаления можно было переместить данные в раздел смерти
--tablespace users
/


--вьюха, представляющая живую часть
create or replace view ttable
as
select * from ttable$ partition(life)
where dead$ is null --чтобы срабатывало check option
with check option
/
 
--при попытке удаления, данные перемещаются в раздел смерти
create or replace trigger trig_ttable_iod
instead of delete on ttable
begin
    update ttable$ partition (life)
    --set dead$ = sdel.NEXTVAL    --чтобы работали уникальные ключи
    set dead$ = current_timestamp   --если используется тип timestamp
    where table_id = :old.table_id
    ;
end;
/

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


--тестовый пример
insert into ttable(table_id, descr)
values( 1 , 'aaa')
/
insert into ttable(table_id, descr)
values( 2 , 'aaa')
/
delete from ttable
/
insert into ttable(table_id, descr)
values( 1 , 'aaa')
/
insert into ttable(table_id, descr)
values( 2 , 'aaa')
/
delete from ttable
/
insert into ttable(table_id, descr)
values( 1 , 'aaa')
/
insert into ttable(table_id, descr)
values( 2 , 'aaa')
/
commit
/
Но реально сейчас для таблиц, которые меняются юзерами в основном построчно, ( а не массово - пакетными задаными ), используем лог изменений. Это одна отдельная нескоростная таблица на все, из которой можно вытащить любую историю, кто, что, когда и откуда.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33629763
nik_x
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_spy_ vadiminfoТ.е. тада надо будет написать запросы на соединение даже если главная табла не нужна? А када нужна - тада для этих табл другие view, чтобы избежать этих соединений? А када удаление из дочерних таблов то все то же?
Да, все же вариант с каскадной простановкой статусов при логическом удалении главной записи видится более предпочтительным.

Если будешь реализовывать через VIEW, то изменение статуса (например атрибут DELETED as DATE_TIME is not NULL), то менять каскадно вообщем-то ничего и не придется. Пользователь просто не увидит этих данных, т.к. они связаны.
А вообще-то системе можно разрешить и "удалять" записи. Вызывая в триггере PRE/POST-DELETE либо прекращение операции удаления, с изменением атрибута DELETED (PRE), либо дублирование записи (POST) и удаление оригинальной. Это зависит от выбранной СУБД.
Правда обычно добавляют и атрибут DELETED_BY.

Единственное с чем соглашусь, есть класс задач (очень маленький и специфичный) где это нужно. А в большенстве случаев можно прожить и без оной задумки...
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33629878
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nik_xЕсли будешь реализовывать через VIEW, то изменение статуса (например атрибут DELETED as DATE_TIME is not NULL), то менять каскадно вообщем-то ничего и не придется. Пользователь просто не увидит этих данных, т.к. они связаны.
Я так понимаю, Вы имеете в виду следующее: если в мастер-таблице есть признак удаления и есть вьюха живых записей, то каскадного логического удаления дочерних записей не потребуется, поскольку пользователь просто "не дойдет" до этих записей по интерфейсу программы.

Если так - не согласен. Причина этого очень проста: практически в любой нетривиальной системе существуют бизнес-функции, использующие позиции документа в отрыве от их заголовков. Скажем, отчеты наподобие оборотно-сальдовой ведомости вполне могут быть построены именно таким образом. Соответственно, в этом случае Ваш подход требует притягивания заголовков и проверки в них статуса записи везде, где используются позиции. Что есть неудобно для разработчика, неоптимально для сервера и прежде всего элементарно ненадежно.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33629903
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerЕсли так - не согласен. Причина этого очень проста: практически в любой нетривиальной системе существуют бизнес-функции, использующие позиции документа в отрыве от их заголовков. Скажем, отчеты наподобие оборотно-сальдовой ведомости вполне могут быть построены именно таким образом. Соответственно, в этом случае Ваш подход требует притягивания заголовков и проверки в них статуса записи везде, где используются позиции. Что есть неудобно для разработчика, неоптимально для сервера и прежде всего элементарно ненадежно.
Угу а если физически удалять запись, то нужно следить чтоб везде удалялись хвосты иначе, см выше "в любой нетривиальной системе существуют бизнес-функции..."
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33629907
nik_x
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
- Да не согласен я.
- С кем? С энгельсом или с Каутским?
- С обоими, - ответил Шариков.
- Это замечательно, клянусь богом. "Всех, кто скажет, что другая..." А
что бы вы со своей стороны могли предложить?
- Да что тут предлагать?.. А то пишут, пишут... Конгресс, немцы
какие-то... Голова пухнет. Взять все, да и поделить...

Булгаков.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33630068
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EstetsУгу а если физически удалять запись, то нужно следить чтоб везде удалялись хвосты иначе, см выше "в любой нетривиальной системе существуют бизнес-функции..."
Если физически удалять запись, то хвосты удалятся каскадом, если нормально схему спроектировать.


To Ненавижу регистрацию
Спасибо за пример.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33630320
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EstetsУгу а если физически удалять запись
То во-первых, я выше аргументировал, почему так в большинстве случаев делать нельзя. Во-вторых, внешние ключи в этом случае уберегут от излишней забывчивости всех, кроме следующих Вашему дизайну без constraint-ов. В-третьих же таки Вы правы и именно это я и доказываю: к "хвосту" в любой реальной системе следует относиться тщательно и аккуратно, иначе будут проблемы.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33631694
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerТо во-первых, я выше аргументировал, почему так в большинстве случаев делать нельзя. Во-вторых, внешние ключи в этом случае уберегут от излишней забывчивости всех, кроме следующих Вашему дизайну без constraint-ов. В-третьих же таки Вы правы и именно это я и доказываю: к "хвосту" в любой реальной системе следует относиться тщательно и аккуратно, иначе будут проблемы.
Вы за Энгельса будете или за Каутского? ;)
Согласен, лишних данных в системе не бывает. У нас физически удаляются только следующие данные:
1) Настройки (метаинформация) - поскольку доступ к ним имеет только администратор и ему и отвечать за внесенные исправления.
2) Агрегированная информация - например расситанные и сохраненные данные для отчетов, т.к. в случае необходимости можно эти данные расчитать еще раз.
3) Информация из внешних источников - опять-же если удаленная информация потребуется вновь, то ее можно будет восстановить.

А по поводу "каскадного удаления" vs "каскадного проставления признака неактуальный", то если это делать триггерами затраты на программирование примерно одинаковые.

Хотя замечу, что у нас нет каскадного обновления статусов записей, и вполне возможен вариант когда есть актуальный перечень, для неактуалной накладной. НО я ни разу не сталкивался с данной проблемой т.к. связанные перечни обрабатываются в связке с основным документом и проверяется "неудаленность" как позиции в перечне (так как она сама мола быть удалена) так и основного документа.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33631847
nnov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_spy_Хотелось бы узнать мнение на тему, кто как организует логическое удаление записей в БД (когда они удаляются на уровне пользователей, но физически продолжают присутствовать в БД) и какие в связи с этим преимущества и недостатки. Сейчас я вижу 2 варианта:
1. Пометка записи на удаление, т.е. введение поля статуса записи.
2. Введение в схему БД дополнительных таблиц для удаленных записей со структурой, совпадающей с оригинальной и перенос туда записей при удалении.

Могу предложить третий вариант, этот вариант использовался в банковсой системе которую я 2 года назад обслуживал, а сейчас я его реализовал в своей системе документооборота.
Принцип вытекает из второго варианта, но только я не статус записи ввел
а время действия документа Date_Begin и Date_End и состояние
Пока запись актуальна Date_End = '01.01.2099:00:00:00' при удалении или любом изменении Date_End = Now
все изменения делаются только процедурами, так легче и гибче можно отслеживать права. Процедура при любом изменении записи, делает ее копию с новым состоянием (включая все подчиненные таблицы) и проставляет даты начала конца.
Этот подход позволяет видеть данные на любой момент времени, обеспечивает непротиворечивость отчетности со временем, ну и естественно всю историю изменений.
...
Рейтинг: 0 / 0
Логическое удаление записей
    #33632107
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To nnov
Спасибо за вариант.
В принципе, такая подробная "историчность" и версионность данных не требуется. Однако поле с датой удаления - это нужная информация, тем более, что я думаю как раз на поле с датой удаления расширять уникальные ключи.
Кроме того, думаю сделать отдельную таблицу дополнительной информации об удаленных объектах, где будут поля
ID объекта
Тип объекта
Пользователь, удаливший запись
Причина удаления

Эта таблица не будет использоваться при работе обычных пользователей, она будет доступна только пользователям, имеющим доступ к удаленным записям.
Таким образом, получается где-то комбинированный подход - с одной стороны для логического удаления используется статус, с другой стороны, есть отдельная таблица с дополнительной информацией об удаленных объектах.
Хотелось бы узнать мнения...
...
Рейтинг: 0 / 0
25 сообщений из 81, страница 1 из 4
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Логическое удаление записей
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]