Реализация мягкого удаления с минимальным влиянием на производительность и код - PullRequest
2 голосов
/ 10 сентября 2011

Есть несколько похожих вопросов по теме, но они на самом деле мне не помогают.

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

  • Добавить логическое поле is_deleted.

    • Преимущества: просто.
    • Недостатки: нет записи даты. Заставляет меня добавлять is_deleted = 0 в каждый запрос.
  • Добавить deleted_date поле даты. Это значение равно NULL, если оно не удалено.

    • Преимущества: имеет дату.
    • Недостатки: все еще загромождаю мои запросы.

Для обоих вышеперечисленных

  • Это также повлияет на производительность, потому что есть все эти бесполезные строки. Они все еще должны поддерживаться в индексах. Также индекс для столбца deleted не поможет при извлечении не удаленных (большинства) строк. Необходимо полное сканирование таблицы.

Другой вариант - создать отдельную таблицу для хранения удаленных элементов:

  • Преимущества: улучшена производительность при запросе не удаленных строк. Нет необходимости добавлять условия к моим запросам на не удаленных строках. Проще на обслуживание индекса.
  • Недостатки: сложность: требуется перенос данных как для удаления, так и для удаления. Нужны новые столы. Ссылочная целостность сложнее обрабатывать.

Есть ли лучший вариант?

Ответы [ 5 ]

3 голосов
/ 10 сентября 2011

Я бы основывал свой ответ на том, как часто вы ожидаете, что ваши пользователи захотят получить доступ к этим удаленным данным или "восстановить" эти удаленные данные.

Если это часто, то я бы пошел с полем "Date_Deleted" и поместил вычисленный "IsDeleted" в моем poco в коде.

Если это никогда (или почти никогда), тогда таблица истории или удаленная таблица полезна для объясненных вами преимуществ.

Лично я почти никогда не использую удаленные таблицы (и выбираю isDeleted или date_deleted) из-за потенциального риска ссылочной целостности. У вас есть A -> B, и вы удаляете запись из базы данных B ... Теперь вам нужно управлять ссылочной целостностью из-за вашего выбора дизайна.

2 голосов
/ 10 сентября 2011

Если ключ числовой, я обрабатываю «мягкое удаление» путем отмены ключа.(Конечно, не будет работать для ключей идентификации).Вам вообще не нужно менять код, и вы можете легко восстановить запись, умножив ее на -1.

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

2 голосов
/ 10 сентября 2011

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

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

1 голос
/ 16 мая 2016

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

Использование одной таблицы с удаленным флагом: Если все ваши индексы сначала содержат поле удаленного флага, а ваш запрос в основном содержит структуру типа where isdeleted = false, то это решает проблемы производительности, и индексы очень эффективно исключают удаленные строки. Аналогичная логика может быть использована для удаленной опции даты.

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

1 голос
/ 16 мая 2016

Предположим, мы создаем поле с именем dead, чтобы отметить удаленные строки.Мы можем создать индекс, где поле dead имеет значение false.Таким образом, мы ищем только не удаленные строки, используя индекс использования подсказок.

...