Впервые разрабатываю систему управления неким предприятием, так же впервые столкнулся с такой проблемой как удаление данных из БД.
Расскажу о сути проблемы через пример:
Необходимо разработать несколько модулей, два из которых: Прайс-лист и журнал продаж.
Изменяющийся ассортимент услуг и товаров для каждой компании это нормально, позиции в прайсе могут удаляться и создаваться. Насчет последнего все просто. Создал новую запись — и дело в шляпе, однако с удалением не все так просто: Трудно будет объяснить аналитикам, почему же они видят строки «22.07.2010 было продано 228 штук „товар ненайден“» в своем журнале.
Тут мы подходим к такой теме как логическое удаление (или soft delete).
Звучит заманчиво: универсальное решение, которое позволяет помечать строки в БД как удаленные, и тем не менее физически не удалять их. Только вот на практике это может превратить любой запрос, даже самый тривиальный, в кладезь ошибок и boilerplate кода.
Есть вариант сделать таблицу/БД-двойник, в которую будут перемещаться удаленные записи. Те запросы которые нуждаются в удаленных записях должны явно указывать при обращении к DAO параметр necroModeOn. Ну или делать отдельные методы/реализации DAO для доступа к архивным таблицам/БД.
Но мне почему-то (vanga.jpg) кажется что в этом решении есть свои подводные камни.
Добрейшие, подскажите пожалуйста, как лучше поступить в данной ситуации?
- Если вы реализовывали классическое логическое удаление (
WHERE deleted = 0
) то расскажите насколько вы намучились (и намучились ли?)?
- Насколько хорош вариант с VIEW?
- Может быть в MySQL есть какие-нибудь волшебные фичи для таких ситуаций?
UPDATE:
Хочу немного уточнить, вопрос, почему же мне все таки не нравится вариант с дополнительным полем с флагом удаления (или временем удаления или статусом — одно и то же).
Мне хочется сравнить этот подход со способом обработки ошибок в современных императивных языках (try-catch-finally) и подходом с возвращением кода ошибки.
Подход с возвращением кода ошибки захламляет код и логику программы. Стоит один раз забыть проверить код ошибки и неясно чего ожидать.
Тут похожая ситуация. Я себе представляю кучу способов прострелить себе коленку с помощью такого подхода.
Кроме того, это ухудшает читабельность запросов и усложняет устройство DAO. Это мешает в одной таблице мертвецов и живые строки, что может негативно повлиять на производительность в горячих таблицах. В join'ах вышеперечисленное ×2.