Следует ли мне удалить или отключить строку в реляционной базе данных?

В совершенно новой программе, где пространство на самом деле не так уж важно, что лучше: удалить строку или отключить строку, скажем, логическим значением «Отключено», и программа просто проигнорирует его?

Например, если я хотел удалить пользователя из программы.

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
31
0
12 622
18

Ответы 18

Это суждение, но я закончил тем, что добавил «отключенные» столбцы в таблицы, где раньше думал, что могу просто удалить строку. Я бы сказал, что в большинстве случаев безопаснее добавлять отключенный столбец. Однако это может быть сложно с отношениями n: n, так что это то, что нужно учитывать.

Как это сложно с записями о перекрестках? Я думаю, что к отношениям применима та же логика, что и к сущностям.

dkretz 07.12.2008 06:28

Потому что связь между двумя записями может быть «удалена», что означает, что они больше не связаны, но когда-то были. А что, если кто-то захочет восстановить отношения? Это может быть проблемой не для всех приложений.

Draemon 07.12.2008 11:29

По-разному. (Но я уверен, что вы уже догадались.)

На практике нарушение правильного использования здесь почти всегда в сторону удаления.

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

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

Слишком много случаев, когда пользовательские или программные проблемы заставляют кого-то нажимать большую кнопку «Отменить»; если вы удалите, вам не повезло (по крайней мере, без специальной помощи и раздражения людей, с которыми вы бы предпочли быть любезными).

Обычно я использую терминологию «Активный» и «Неактивный».


Еще несколько моментов для рассмотрения (от Totophil):

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

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

Обычно я использую терминологию "Активный" и "Неактивный". ... Я почти всегда добавляю это как дополнительное поле в таблицы с первичным ключом. Как логическое значение, он занимает минимум места и обеспечивает надлежащую целостность данных, давая приложению воспринимаемое удаление. Единственный случай, когда это обременительно, - это случайная вставка с последующим немедленным удалением.
Sablefoste 06.01.2017 20:47

По-разному. Если он отключен, легче восстановить / увидеть, что кто-то действительно удалил запись (для аудита).

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

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

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

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

Не удаление приведет к созданию нового класса ошибок для всех будущих запросов. Не забывайте, что написание запросов часто выполняется опытными пользователями (т. Е. Не ИТ-специалистами) и младшими разработчиками. Итак, теперь для каждой таблицы, в которой есть недопустимые данные, отмеченные только активным флагом BIT, потребуется дополнительное И в предложении WHERE для каждого запроса с настоящего момента и до бесконечности. Это поможет пользователям попасть в яму неудач, а не успеха. Тем не менее, я настоятельно рекомендую вам реализовать эти системы флагов в любом случае, потому что без плохого дизайна разработчикам обслуживания нет необходимости исправлять многочисленные ошибки, которые это создаст.

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

Он был удален из-за ошибки? Если строка соответствует сущности в реальной жизни, возможно, будет интересно оставить и установить флажки «испарился», «мертв», «покинул здание». Если вы случайно вставили строку, которая не соответствует ни одному объекту в реальной жизни, DELETE - неплохая вещь. Важны ли воображаемые покупатели, которых никогда не было?

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

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

Chris 07.12.2008 08:52

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

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

Это должно определяться потребностями приложения. Я сделал это обоими способами. У меня есть приложения, которые должны поддерживать отмену, поскольку стоимость удаления строки - и вызываемые этим каскадные удаления - слишком дороги, чтобы ее не было. Однако обычно приложения, которые я сделал, требуют от пользователя подтверждения удаления, а затем просто делают, как пользователь попросил. В некоторых случаях вы должны удалить данные из соображений конфиденциальности. То есть, если пользователь запрашивает удаление, вам нужно действительно удалить его, а не просто пометить как устаревший. В других случаях (например, при транзакциях, связанных с налогами) могут быть причины хранить данные в неактуальном состоянии до тех пор, пока они не станут больше необходимыми по закону. У меня есть приложения, которые подходят обеим категориям.

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

Прочитав книгу о дизайне темпоральных баз данных, я пришел к убеждению в том, что каждая запись, имеющая временное значение, должна иметь как минимум 4 столбца временных меток. Эти четыре: создано, удалено, начало, конец. Созданные и удаленные отметки времени говорят сами за себя. Ваша система не должна просматривать записи, удаленные ранее (). Столбцы начала и конца определяют, когда данные применяются в вашей системе. Это для ведения истории изменений. Если вам нужно обновить запись, вы должны установить время ее окончания на now (), скопировать ее, обновить копию и установить время начала копии на now (). Таким образом, когда вам нужно посмотреть на то, как что-то было исторически, вы можете попросить систему выяснить это. Вы также можете установить начало на какой-то момент в будущем, чтобы изменение происходило автоматически в это время, или установить конец на будущее время, чтобы оно автоматически исчезло в это время. Установка временных меток создания / удаления в будущее на самом деле не имеет смысла ...

Какая книга? Вроде интересно.

bortzmeyer 08.12.2008 15:14

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

Martin Brown 16.12.2008 19:29

Добавление столбца «УДАЛЕННЫЙ» в вашу таблицу и маркировка строк вместо их удаления создает для вас гораздо больше работы с небольшими преимуществами (если таковые имеются). Теперь каждый раз, когда вы пишете запрос, вы должны не забывать включать «WHERE DELETED IS NOT NULL» (или что-то еще).

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

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

Я надеюсь, что это будет Deleted! = 'Y' или Deleted = 'N' или подобное, а не нули. И просмотры могут быть полезны на этом этапе.

Jonathan Leffler 07.12.2008 10:34

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

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

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

Если вам иногда понадобятся удаленные данные, но не очень часто: вы можете переместить записи в отдельную базу данных / table (например, users и users_deleted, или лучше somedb.users и somedb_deleted.users).

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

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

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

Как многие уже говорили, приложение должно диктовать, что вы хотите делать. Но мне кажется, что разметка строки - это неправильный инструмент. Мы логически думаем об удалении как об УДАЛЕНИИ, поэтому, если вам не разрешено удаление по юридическим причинам, вы не удаляете его в первую очередь. В то же время я думаю о хранении и индексации всей внутренней структуры данных. Не говоря уже о всех оптимизациях, которые могут быть выполнены для получения данных, но добавление этой проверки (в представлении или в запросе) влияет на производительность экспоненциально в зависимости от сложности базы данных и отношений между сущностями.

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

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

Вы можете запретить пользователю удалять запись, если это вызовет проблемы с ссылочной целостностью, используя ограничения внешнего ключа (при условии, что ваша СУБД поддерживает это). Несколько раз я сообщал конечному пользователю: «Вы не можете удалить этот <объект>, пока не отключите от него <родительский объект>». Это может работать до тех пор, пока вы не ожидаете чрезвычайно большого количества ассоциаций с другой таблицей или таблицами.

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

Я создаю CRUD и сталкиваюсь с той же проблемой.

Решение: D CRUD следует отключить, а не удалить.

Проблемы:

  • «Каждый» запрос должен проверять, отключен ли реестр (например, flag = 1). В частности, ever select * должен это проверить.
  • Каждая вставка должна активировать реестр (флаг = 1) по умолчанию.
  • Обновление не должно менять флаг.
  • Отключить - это замаскированное обновление, которое отмечает флаг = 0.

Большая проблема

  • Уборщик мусора. Существует три стратегии: удаление старых реестров, удаление реестров, на которые нет ссылок, или сочетание стратегий.

Другие вопросы по теме