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

проблема

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

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

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

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

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

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

Твои мысли?

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

Solutions Collecting From Web of "Рекомендации по безопасному удалению (PHP / MySQL)"

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

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

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

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

Наличие двух других уровней позволит администраторам и администраторам очищать удаленные списки, если они слишком длинны. И поскольку код интерфейса просто проверяет is_deleted = 0 , он прозрачен для интерфейса …

Использование soft-delete – это обычная вещь для реализации, и они полезны для многих вещей, например:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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