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

Каков наилучший способ реализации мягкого удаления?

В данный момент мы работаем над проектом, и мы должны реализовать мягкое удаление для большинства пользователей (пользовательских ролей). Мы решили добавить поле is_deleted='0' для каждой таблицы в базе данных и установить его на '1', если определенные роли пользователя нажимают кнопку удаления в определенной записи.

Для будущего обслуживания сейчас каждый запрос SELECT должен убедиться, что он не включает записи where is_deleted='1'.

Есть ли лучшее решение для реализации мягкого удаления?

Обновление: я должен также отметить, что у нас есть база данных аудита, которая отслеживает изменения (поле, старое значение, новое значение, время, пользователь, IP) во всех таблицах/полях в базе данных приложения.

4b9b3361

Ответ 1

Вы можете выполнить все ваши запросы против представления, содержащего предложение WHERE IS_DELETED='0'.

Ответ 2

Я бы склонился к столбцу deleted_at, который содержит дату времени, когда произошло удаление. Затем вы получите немного бесплатных метаданных об удалении. Для вашего SELECT просто получите строки WHERE deleted_at IS NULL

Ответ 3

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

В результате, если вы введете запрос типа

SELECT * FROM table_name WHERE is_deleted = 1

тогда Oracle выполнит "сокращение раздела" и заглянет только в соответствующий раздел. Внутренне раздел - это другая таблица, но она прозрачна для вас как пользователя: вы сможете выбирать по всей таблице независимо от того, секционирована она или нет. Но Oracle сможет запрашивать ТОЛЬКО тот раздел, который ему нужен. Например, предположим, что у вас есть 1000 строк с is_deleted = 0 и 100000 строк с is_deleted = 1, и вы разбили таблицу на is_deleted. Теперь, если вы включите условие

WHERE ... AND IS_DELETED=0

тогда Oracle будет сканировать ТОЛЬКО раздел с 1000 строками. Если бы таблица не была разбита на части, ей пришлось бы сканировать 101000 строк (оба раздела).

Ответ 4

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

В SQL Server лучшим решением было бы использовать столбец deleted_on/deleted_at с типом SMALLDATETIME или DATETIME (в зависимости от необходимой степени детализации) и сделать этот столбец нулевым. В SQL Server данные заголовка строки содержат битную маску NULL для каждого из столбцов в таблице, поэтому она немного быстрее выполняет IS NULL или IS NOT NULL, чем проверка значения, хранящегося в столбце.

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

Я обычно избегаю полей флага, таких как is_deleted, is_archive и т.д., потому что они несут только один смысл. Поле nullable deleted_at, archived_at предоставляет дополнительный уровень значения самому себе и тому, кто наследует ваше приложение. И я избегаю полей битмаски, таких как чума, поскольку они требуют понимания того, как была построена битовая маска, чтобы понять смысл.

Ответ 5

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

таким образом вам не нужно добавлять другой столбец в свою основную таблицу

Ответ 6

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

Вы хотите иметь возможность:

  • знать, какая информация была (до ее удаления)
  • знать, когда он был удален?
  • знать, кто удалил его?
  • знать, в какой степени они действовали, когда удалили его?
  • можно удалить запись?
  • быть в состоянии сказать, когда он не был удален?
  • и др.

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

Ответ 7

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

Подумайте о цикле:

  • создать пользователя (login = JOE)
  • soft-delete (установите удаленный столбец в ненулевой.)
  • (re) создать пользователя (login = JOE). ОШИБКА. LOGIN = JOE уже принято

Вторые создают результаты в нарушении ограничений, потому что login = JOE уже находится в строке с мягким удалением.

Некоторые методы:  1. Переместите удаленную запись в новую таблицу.  2. Сделайте свое ограничение уникальности в столбце временной метки login и deleted_at

Мое собственное мнение - +1 для перехода на новый стол. Его много   дисциплина для поддержания * И delete_at = NULL * во всех ваших   запросов (для всех ваших разработчиков)

Ответ 8

У вас будет определенная производительность, если вы переместите ваши удаленные данные в другую таблицу, как сказал Джим, а также записью о том, когда она была удалена, почему и кем.

Добавление where deleted= 0 ко всем вашим запросам значительно замедлит их и будет препятствовать использованию любых индексов, которые могут быть у вас в таблице. Избегайте наличия "флагов" в ваших таблицах, когда это возможно.

Ответ 9

вы не указываете, какой продукт, но SQL Server 2008 и postgresql (и другие, я уверен) позволяют создавать отфильтрованные индексы, поэтому вы можете создать индекс покрытия, где is_deleted = 0, смягчая некоторые из негативов этот конкретный подход.

Ответ 10

Что-то, что я использую для проектов, - это statusInd tinyint, а не нулевой столбец по умолчанию 0 using statusInd как битовая маска позволяет мне управлять данными (удалять, архивировать, копировать, восстанавливать и т.д.). Используя это в представлениях, я могу затем выполнить распределение данных, публикацию и т.д. Для приложений-потребителей. Если производительность вызывает озабоченность в отношении представлений, используйте небольшие таблицы фактов, чтобы поддержать эту информацию, отбросив этот факт, отбросив связь и разрешив удаленные удаления.

Хорошо масштабируется и ориентирован на данные, сохраняя незначительный размер данных - ключ для 350 гб + dbs с проблемами в реальном времени. Использование альтернатив, таблиц, триггеров имеет некоторые накладные расходы, которые в зависимости от необходимости могут или не могут работать для вас.

Аудиты, связанные с SOX, могут потребовать больше, чем поле, чтобы помочь в вашем случае, но это может помочь. Наслаждайтесь

Ответ 11

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

Ответ 12

Используйте представление, функцию или процедуру, которая проверяет is_deleted = 0; то есть не выбирайте непосредственно на таблицу, если таблица должна быть изменена позже по другим причинам.

И индексируйте столбец is_deleted для больших таблиц.

Поскольку у вас уже есть контрольный журнал, отслеживание даты удаления является излишним.

Ответ 13

Создайте другую схему и выделите ее на схеме данных. Implment VPD на вашей новой схеме, чтобы каждый запрос имел предикат, позволяющий выбирать только не удаленные строки, добавленные к нему. http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/cmntopc.htm#CNCPT62345