К сожалению, наилучший ответ зависит от того, чего вы пытаетесь достичь с помощью программных удалений, и от базы данных, в которой вы реализуете это.
В SQL Server лучшим решением было бы использование столбца dele_on / dele_at с типом SMALLDATETIME или DATETIME (в зависимости от необходимой детализации) и сделать этот столбец пустым. В SQL Server данные заголовка строки содержат битовую маску NULL для каждого из столбцов таблицы, поэтому выполнение IS NULL или IS NOT NULL немного быстрее, чем проверка значения, хранящегося в столбце.
Если у вас большой объем данных, вы можете захотеть разбить данные на части либо через саму базу данных, либо через две отдельные таблицы (например, Products и ProductHistory), либо через индексированное представление.
Я обычно избегаю полей флагов, таких как is_deleted, is_archive и т. Д., Потому что они несут только одну часть значения. Обнуляемое поле delete_at, archived_at обеспечивает дополнительный уровень значимости для вас и любого, кто наследует ваше приложение. И я избегаю таких полей битовой маски, как чума, поскольку они требуют понимания того, как была создана битовая маска, чтобы понять любой смысл.