Я думаю, что ваш анализ вариантов хорош, но вы упустили несколько важных моментов, которые я перечислю ниже. Почти все реализации, которые я видел, используют в строке какое-то поле для удаления или управления версиями, как вы предлагаете в первых двух вариантах.
Использование одной таблицы с удаленным флагом:
Если все ваши индексы сначала содержат поле удаленного флага, а ваш запрос в основном содержит структуру типа where isdeleted = false, то это решает проблемы производительности, и индексы очень эффективно исключают удаленные строки. Аналогичная логика может быть использована для удаленной опции даты.
Использование двух таблиц
Как правило, вам необходимо вносить значительные изменения в отчеты, поскольку некоторые отчеты могут ссылаться на удаленные данные (например, старые цифры продаж могут относиться к категории удаленных продаж). Это можно преодолеть, создав представление, представляющее собой объединение двух таблиц для чтения и записи только в таблицу активных записей.