2013-12-15 4 views
2

Iv'e только что услышал от коллеги, что удаление строк на реляционную БД является довольно опасным (относительно индексации и каскадных действий)Реляционные базы данных - удалять или не удалять?

Он сказал, что одно решение для обеспечения возможности удаления должны иметь «устаревшее» поле для каждого объекта и вместо этого установите для поля значение true, чтобы пометить строку как «удаленную».

, конечно, потребует от вас на все ваши запросы, чтобы принести все «выделенные» == лжи (что является довольно громоздким)

Моими вопросов:

  1. ли он прав? если это так - что конкретно опасно для удаления?
  2. Является ли его решение хорошей практикой?
  3. Доступны любые альтернативы этому решению?

спасибо.

+0

http://stackoverflow.com/a/820489/477878 –

ответ

2

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

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

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

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

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

+0

Не обязательно не согласен, но почему это даст лучшую производительность для удаления? Отсутствие фильтрованных индексов в MySQL? –

+1

У меня есть опыт из первых рук с чрезвычайно медленными пакетными удалениями в большой таблице. –

+0

вы уверены, что это не та база данных, которая вызывает эту медлительность? –

1

Опасный? Взорвется ли сервер или дата-центр?

Я думаю, что ваш коллега потакает некоторой гиперболе.

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

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

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

1
  1. Да, он прав.Базы данных (индексы, в частности) оптимизированы для вставки и удаления, могут быть очень медленными. Даже установка индексированного поля в значение null может вызвать те же проблемы. Я рассматриваю каскадирование как меньшую проблему, потому что db никогда не должен быть настроен на автоматическое каскадирование.

  2. Да, помеченная запись как «неактивная», «удаленная», «устаревшая» (ваш выбор) является стандартной и предпочтительной практикой для решения проблемы производительности, связанной с удалением.

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

  3. Другой подход состоит в том, чтобы просто не иметь транзакционную таблицу с миллионами строк. Переместите данные в архивную таблицу до того, как она вырастет до таких пропорций.

1

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

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

  • Как вы сказали, программирование становится немного сложнее, потому что вы должны помнить, что каждый SELECT теперь должен включать в себя WHERE deleted = false.
  • Когда вы часто удаляете данные, ваша база данных будет накапливать много трещин. Это заставит его расти, что влияет на производительность и использует ненужное место на диске.
  • Когда ваши пользователи вынуждены удалять данные из-за правил конфиденциальности, и они предполагают, что нажатие кнопки «удалить» действительно удаляет его, эта практика может непреднамеренно привести к нарушению этих правил.
+1

Я думаю, что обновляемое представление может помочь с проблемой №1, хотя я лично не пробовал это с MySQL. –

+0

+1 для написания всего, что я хотел написать, но путь быстрее :) – flup

1

Этот вопрос имеет несколько уровней. В целом рекомендуется помечать строки как удаленные, а не удалять их вообще.

Есть несколько основных преимуществ:

  1. Данные возмещен. Вы можете обеспечить восстановление для пользователей.
  2. Обновление происходит быстрее, чем удаление.
  3. В общедоступном приложении ни один из общедоступного кода не имеет истинного удаления, что делает его намного сложнее использовать этот код для ненадлежащих целей (sql-инъекция и т. Д.).
  4. Если вы когда-либо захотите сообщить в своих данных ты можешь.

Есть, конечно, предостережений и передовой практики:

  1. Это не относится к справочным таблицам с легко восстановить данные.
  2. Вам необходимо рассмотреть вопрос об отбраковке.В наших базах данных мы удаляем записи в архивные таблицы отчетов. Это быстро сохраняет основные таблицы, но позволяет нам сообщать о данных, связанных с «удаленными» элементами.
  3. Ваше влияние на производительность отбраковки (в больших масштабах) будет аналогично резервной копии и имеет аналогичные соображения. Запускайте их в нерабочее время, если вы хотите архивировать их все сразу или периодически через cron, если вы хотите просто взять номер X в час.
  4. НИКОГДА не использует удаленные данные в ваших данных в реальном времени. Другими словами, это не флаг состояния! Это ушло. Я допустил эту ошибку раньше и отменил ее, это было больно.
  5. Если в таблице содержится очень большой процент удалений, спросите себя, действительно ли важно хранить данные. Вы можете настроить процесс отбраковки, чтобы не архивировать, а вместо этого просто запустить фактическое удаление.

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

Смежные вопросы