Подтвердить что ты не робот

Рекомендации по безопасному удалению (PHP/MySQL)

Проблема

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

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

Я думаю о внедрении soft-deletion. Итак, как обычно это делается?

Мои непосредственные мысли

Моя первая мысль - вставить столбец "flag_softdeleted TINYINT NOT NULL DEFAULT 0" в каждую таблицу объектов, которые должны быть мягко удаляемыми. Или, может быть, вместо этого используйте временную метку?

Затем я предоставляю кнопку "Показать удаленные" или "Восстановить" в каждом соответствующем графическом интерфейсе. Нажав на эту кнопку, вы введете записи с мягким удалением. Каждая удаленная запись имеет кнопку "Восстановить". Это имеет смысл?

Ваши мысли?

Кроме того, я был бы признателен за любые ссылки на соответствующие ресурсы.

4b9b3361

Ответ 1

Как я это делаю. У меня есть поле is_deleted, которое по умолчанию равно 0. Затем запросы просто проверяют WHERE is_deleted = 0.

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

Изменить: Фактически вы можете использовать это, чтобы иметь несколько "слоев" для мягкого удаления в вашем приложении. Таким образом, каждый может быть кодом:

  • 0 → Не удалено
  • 1 → Soft Deleted, отображается в списках удаленных элементов для пользователей управления.
  • 2 → Soft Deleted, не отображается для любого пользователя, кроме пользователей admin
  • 3 → Только для разработчиков.

Если остальные 2 уровня по-прежнему позволят администраторам и администраторам очищать удаленные списки, если они становятся слишком длинными. А поскольку код переднего конца просто проверяет is_deleted = 0, он прозрачен для внешнего интерфейса...

Ответ 2

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

  • Сохранение пользовательской вставки при удалении чего-либо.
  • Сохранение собственной жопы, когда вы что-то удаляете
  • Сохраните послужной список того, что действительно произошло (своего рода аудит).
  • и так далее

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

Существуют разные степени удаления. Типичный пользователь удаляет материал, когда он

  • Сделал ошибку и хочет удалить плохие данные.
  • Больше не хочет видеть что-то на экране

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

Посмотрите на следующие данные:

PRICES | item | price | deleted |
       +------+-------+---------+
       |   A  |  101  |    1    |
       |   B  |  110  |    1    |
       |   C  |  120  |    0    |
       +------+-------+---------+

Некоторые пользователи не хотят показывать цену товара B, так как они больше не продают этот товар. Поэтому он удаляет его. Другой пользователь установил цену за элемент А по ошибке, поэтому он удалил ее и создал цену для элемента C, как и предполагалось. Теперь вы можете показать мне список цен на все продукты? Нет, потому что либо вы должны отображать потенциально опасные данные (A), либо вы должны исключать все, кроме текущих цен (C).

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

Ответ 3

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

Ответ 4

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

Некоторые компоненты, которые я создаю, позволяют пользователю просматривать все удаленные записи и восстанавливать их, другие просто отображают все записи, где удалено = 0

Ответ 5

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

Я бы сделал архивацию, чтобы избежать значительного обновления производственного кода. Но если вы хотите использовать поле удаленных флагов, используйте его как временную метку, чтобы дать вам дополнительную полезную информацию за пределами логического. (Null = not deleted.) Вы также можете добавить поле DeletedBy, чтобы отслеживать пользователя, ответственного за удаление записи. Использование двух полей дает вам много информации о том, кто удалил что и когда. (Два дополнительных решения для полей также могут быть выполнены в архивной таблице/базе данных.)

Ответ 6

Самый распространенный сценарий, с которым я столкнулся, - это то, что вы описываете, tinyint или даже bit, представляющий статус IsActive или IsDeleted. В зависимости от того, считаются ли данные "бизнес" или "постоянство", они могут быть запечены в логике приложения/домена как можно более прозрачно, например, непосредственно в хранимых процедурах и не известны программному коду. Но похоже, что это законная деловая информация для ваших нужд, поэтому ее нужно будет знать во всем коде. (Таким образом, пользователи могут просматривать удаленные записи, как вы предлагаете.)

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

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