Сценарий состоит в том, что у меня расширяется набор пользователей, и со временем пользователи отменят свои учетные записи, которые мы в настоящее время помечаем как «удаленные» (с флагом) в той же таблице.
Если пользователи с одним и тем же адресом электронной почты (как пользователи входят в систему) желают создать новую учетную запись, они могут зарегистрироваться снова, но создается новая учетная запись. (У нас есть уникальные идентификаторы для каждой учетной записи, поэтому адреса электронной почты могут дублироваться среди живых и удаленных).
Что я заметил, так это то, что во всей нашей системе мы постоянно запрашиваем таблицу пользователей, проверяя, что пользователь не удален, тогда как я думаю, что нам вообще не нужно это делать ... ! [Разъяснение1: под «постоянными запросами» я имел в виду, что у нас есть запросы, которые выглядят так: «... ОТ пользователей, ГДЕ isdeleted =" 0 "И ...". Например, нам может потребоваться получить всех пользователей, зарегистрированных для всех собраний на определенную дату, поэтому в запросе THAT у нас также есть пользователи FROM WHERE isdeleted = "0" - это проясняет мою точку зрения?]
(1) continue keeping deleted users in the 'main' users table
(2) keep deleted users in a separate table (mostly required for historical
book-keeping)
Каковы плюсы и минусы любого подхода?
источник
Ответы:
Вы можете использовать, например, триггер для автоматического перемещения удаленных пользователей в таблицу истории.
источник
Я настоятельно рекомендую использовать ту же таблицу. Основная причина - целостность данных. Скорее всего, будет много таблиц со связями в зависимости от пользователей. Когда пользователь удаляется, вы не хотите оставлять эти записи сиротами.
Наличие осиротевших записей усложняет соблюдение ограничений и затрудняет поиск исторической информации. Другое поведение, которое нужно учитывать, когда пользователь предоставляет использованную электронную почту, если вы хотите, чтобы он восстановил все свои старые записи. Это будет работать автоматически с помощью мягкого удаления. Что касается его кодирования, например, в моем текущем приложении на c # linq, предложение where Удалено = 0 автоматически добавляется в конец всех запросов.
источник
Это дает мне неприятный запах дизайна. Вы должны скрыть такую логику. Например, вы должны
UserService
предоставить методisValidUser(userId)
для использования «по всей вашей системе», а не делать что-то вроде:Ваш способ хранения удаленных пользователей не должен влиять на бизнес-логику.
При такой инкапсуляции приведенный выше аргумент больше не должен влиять на подход вашей настойчивости. Тогда вы сможете больше сосредоточиться на плюсах и минусах, связанных с самой настойчивостью.
Вещи для рассмотрения включают в себя:
Обычно я бы взял комбинированный путь:
источник
Чтобы правильно ответить на этот вопрос, сначала нужно решить: что означает «удалить» в контексте этой системы / приложения?
Чтобы ответить на этот вопрос, вам нужно ответить еще на один вопрос: почему удаляются записи?
Существует ряд веских причин, по которым пользователю может потребоваться удалить данные. Обычно я нахожу, что существует только одна причина (для каждой таблицы), почему удаление может быть необходимым. Вот некоторые примеры:
Есть также несколько очень плохих причин для жесткого удаления (подробнее об этом позже):
Вы спросите, почему это так важно? Что не так с хорошим оле
DELETE
?Итак, мягкое удаление лучше, верно? Нет, не совсем:
Правда в том, что оба эти подхода неверны. Удаление это неправильно. Если вы на самом деле задаете этот вопрос, то это означает, что вы моделируете текущее состояние вместо транзакций. Это плохая, плохая практика в базе данных.
Уди Дахан написал об этом в « Не удалять - просто не делай» . Существует всегда какой - то задачи, сделки, активность , или (мой предпочтительный термин) событие , которое на самом деле представляет собой «Удалить». Это нормально, если впоследствии вы захотите денормализовать в таблицу «текущее состояние» для повышения производительности, но сделайте это после того, как вы завершили транзакционную модель, а не раньше.
В этом случае у вас есть «пользователи». Пользователи по сути являются клиентами. Клиенты имеют деловые отношения с вами. Эти отношения не просто исчезают, потому что они отменили свою учетную запись. Что на самом деле происходит:
В каждом случае это один и тот же клиент и, возможно, одна и та же учетная запись (т. Е. Каждое продление учетной записи является новым соглашением об обслуживании). Так почему вы удаляете строки? Это очень легко моделировать:
Вот и все. Это все, что нужно сделать. Вам никогда не нужно ничего удалять. Выше приведен довольно распространенный дизайн, который обеспечивает хорошую степень гибкости, но его можно немного упростить; Вы можете решить, что вам не нужен уровень «Соглашение», и просто «Account» перейти к таблице «AccountStatus».
Если в вашем приложении часто требуется получить список активных соглашений / учетных записей, то это (немного) хитрый запрос, но для этого нужны представления:
И вы сделали. Теперь у вас есть кое-что со всеми преимуществами программных удалений, но ни с одним из недостатков:
Единственная проблема, которую нужно решить, это проблема производительности. Во многих случаях это на самом деле не является проблемой из-за включенного кластерного индекса
AgreementStatus (AgreementId, EffectiveDate)
- там очень мало запросов ввода-вывода. Но если это когда-либо является проблемой, есть способы решить это, используя триггеры, индексированные / материализованные представления, события уровня приложения и т. Д.Однако не стоит слишком рано беспокоиться о производительности - более важно правильно спроектировать проект, и «правильный» в этом случае означает использование базы данных так, как она предназначена для использования в качестве транзакционной системы.
источник
В настоящее время я работаю с системой, в которой каждая таблица имеет флажок «Удалено» для мягкого удаления. Это проклятие всего существования. Это полностью нарушает реляционную целостность, когда пользователь может «удалить» запись из одной таблицы, но дочерние записи, которые возвращаются в эту таблицу, не каскадно удаляются. Действительно делает для мусорных данных после того, как время проходит.
Итак, я рекомендую отдельные таблицы истории.
источник
Разбить стол на две части было бы самой глупой вещью.
Вот два очень простых шага, которые я бы порекомендовал:
PS Извините за несколько месяцев задержки ответа!
источник
Если бы вы восстанавливали удаленные учетные записи, когда кто-то возвращается с тем же адресом электронной почты, то я бы сохранил всех пользователей в одной таблице. Это сделало бы процесс восстановления учетной записи тривиальным.
Однако, поскольку вы создаете новые учетные записи, вероятно, будет проще перенести удаленные учетные записи в отдельную таблицу. Живой системе эта информация не нужна, поэтому не раскрывайте ее. Как вы говорите, это делает запросы проще и, возможно, быстрее на больших наборах данных. Более простой код также легче поддерживать.
источник
Вы не упоминаете СУБД в использовании. Если у вас Oracle с соответствующей лицензией, вы можете рассмотреть возможность разделения таблицы пользователей на два раздела: активные и удаленные пользователи.
источник