데이터베이스 레코드의 물리적 대 논리적 / 소프트 삭제?


116

레코드를 실제로 또는 물리적으로 삭제하는 것과 반대로 레코드의 논리적 / 소프트 삭제 (즉, 레코드가 삭제되었음을 나타내는 플래그 설정)를 수행하면 어떤 이점이 있습니까?

이것이 일반적인 관행입니까?

안전한가요?


22
플래그가 아닌 삭제 타임 스탬프를 사용하세요.
Dave Jarvis

@DaveJarvis, 타임 스탬프를 사용하는 것이 플래그에 대한 더 나은 접근 방식 인 이유를 설명 할 수 있습니까?
C Henry

4
플래그는 행이 삭제 된 시기 에 대한 정보를 제공하지 않습니다 . 시간 정보는 시스템 디버깅을 포함하여 많은 용도로 사용됩니다.
Dave Jarvis

답변:


70

장점은 기록을 유지하고 (감사에 적합), 삭제하려는 행을 참조하는 데이터베이스의 다양한 다른 테이블을 통해 계단식으로 삭제하는 것에 대해 걱정할 필요가 없다는 것입니다. 단점은 플래그를 고려하기 위해보고 / 표시 방법을 코딩해야한다는 것입니다.

그것이 일반적인 관행 인 한-나는 예라고 말하고 싶지만, 사용 여부는 비즈니스 요구에 달려 있습니다.

편집 : 또 다른 단점에 대한 생각-테이블에 고유 인덱스가있는 경우 삭제 된 레코드는 여전히 "하나"레코드를 차지하므로 그 가능성을 중심으로 코딩해야합니다 (예 : 고유 인덱스가있는 사용자 테이블). 사용자 이름; 삭제 된 레코드는 새 레코드에 대한 삭제 된 사용자 사용자 이름을 계속 차단합니다.이 문제를 해결하려면 삭제 된 사용자 이름 열에 GUID를 추가 할 수 있지만 권장하지 않는 매우 엉뚱한 해결 방법입니다. 아마도 그런 상황에서는 그렇게 될 것입니다. 사용자 이름이 사용되면 절대로 바꿀 수 없다는 규칙을 갖는 것이 좋습니다.)


활성 / 비활성화 된 사용자로 표시 =) 고유 인덱스 (여기서는 데이터베이스가 고유 인덱스를 제어하고 있음을 의미한다고 가정) 인 경우 다른 메모에서 의미하는 바는 무엇입니까?-새 레코드를 위해 삭제 된 사용자 사용자 이름을 여전히 차단합니까 ??
Coops

@CodeBlend-위에서 설명한대로 사용자 이름 열에 고유 인덱스가있는 사용자 테이블이있는 경우 "Chris Shaffer"라는 사용자에 대해 소프트 / 논리적 삭제를 수행하면 해당 사용자 이름을 새 사용자에게 사용할 수 없습니다. 사용자가 새 계정을 만들 수 있지만 하드 / 물리적 삭제를 수행 한 경우 사용자 이름을 다시 사용할 수 있습니다.
Chris Shaffer

아, 사용자 이름 (사용자 이름)이 아닌 행으로 생각하고있었습니다. 전체 기록을 유지하려면 '주문'또는 해당 사용자와 연결된 항목이있는 경우 소프트 / 논리적 삭제를 수행해야합니다.
Coops

11
@ChrisShaffer 또는 GUID 대신 삭제되지 않은 행만 인덱싱하도록 선택할 수 있습니다. 예 : CREATE UNIQUE INDEX ... WHERE DELETED_AT is null(PostgreSQL에서) 삭제 날짜가있는 모든 행이 인덱싱되지 않습니다. (그들은 대신 비 고유 인덱스에 포함 할 수 있습니다.)
KajMagnus

6
@Chris Shaffer : "u는 다른 여러 테이블을 통해 계단식으로 삭제하는 것에 대해 걱정할 필요가 없습니다."라고 말합니다. 사실이 아니라면 소프트 삭제를 수동으로 전달해야하는데, 이는 매우 고통스럽고 불일치를 유발합니다. 더 이상 외래 키 관계 시행이 없기 때문에 이것은 실제로 단점입니다. 곧 데이터 쓰레기로 끝날 것입니다.
Stefan Steiger

27

논리적 삭제가 일반적인 관행입니까? 예, 여러 곳에서 이것을 보았습니다. 안전한가요? 그것은 정말로 당신이 그것을 삭제하기 전의 데이터보다 덜 안전합니까?

제가 기술 책임자 였을 때 저는 우리 팀이 모든 데이터를 보관할 것을 요구했습니다. 당시에는 요구 사항이 무엇인지 몰랐지만 그 모든 데이터를 사용하여 다양한 BI 애플리케이션을 구축 할 것이라는 것을 당시에는 알고있었습니다. 있다. 감사, 문제 해결 및보고의 관점에서는 좋았지 만 (B2B 거래를위한 전자 상거래 / 도구 사이트였으며 누군가 도구를 사용했다면 나중에 계정이 꺼져도 기록하고 싶었습니다), 몇 가지 단점이있었습니다.

단점은 다음과 같습니다 (이미 언급 된 다른 항목 제외).

  1. 모든 데이터를 보관하는 성능 시사점, 다양한 아카이빙 전략을 개발합니다. 예를 들어 애플리케이션의 한 영역은 일주일에 약 1Gb의 데이터를 생성하는 데 가까워졌습니다.
  2. 데이터 유지 비용은 시간이 지남에 따라 증가하지만 디스크 공간은 저렴하지만 온라인 및 오프라인 모두에서 테라 바이트 단위의 데이터를 유지하고 관리하기위한 인프라의 양은 많습니다. 중복성을 위해 많은 디스크가 필요하고 백업이 신속하게 이동하는지 확인하는 데 사람들의 시간이 걸립니다.

논리적, 물리적 삭제 또는 보관을 사용하기로 결정할 때 다음과 같은 질문을합니다.

  1. 테이블에 다시 삽입해야 할 수있는 데이터입니다. 예를 들어 사용자 계정을 활성화하거나 비활성화 할 수 있으므로 사용자 계정이이 범주에 해당합니다. 이 경우 논리적 삭제가 가장 적합합니다.
  2. 데이터 저장에 내재적 가치가 있습니까? 그렇다면 얼마나 많은 데이터가 생성 될 것입니다. 이것에 따라 논리적 삭제를 수행하거나 보관 전략을 구현합니다. 논리적으로 삭제 된 레코드는 항상 보관할 수 있습니다.

사용자 계정 예에서 활성 사용자와 비활성 사용자를 별도의 테이블에 유지하는 것이 좋습니까? 예 : Activated테이블과 Deactivated테이블 스키마 - Id,Name,etc..에서 행 Activated- 1001,Smith007,etc...그가 비활성화되면, 그 다음 우리가 스미스의 모든하지만 ID 열을 지울 수 Activated와 그를 추가 Deactivated.
Erran Morad 2014

Id와 행을 떠나는 경우 모든 데이터를 이동하면 어떤 이점이 있습니까? 아마도 당신의 기록이 거대하다면 마이크로 최적화로 볼 것입니다.
JoshBerke 2014 년

테이블 주변에서 데이터를 이동하는 경우 계단식 외래 키 제약 조건에 행운을 빕니다.
CAD

20

조금 늦을 수도 있지만 논리적 / 소프트 삭제에 대한 Pinal Dave의 블로그 게시물을 모두 확인하는 것이 좋습니다 .

나는 이런 종류의 디자인 [소프트 삭제]이 전혀 마음에 들지 않습니다. 저는 필요한 데이터 만 단일 테이블에 있어야하고 쓸모없는 데이터는 보관 된 테이블로 이동해야하는 아키텍처를 굳게 믿습니다. isDeleted 열을 따르는 대신에 주문이있는 테이블과 삭제 된 주문이있는 다른 두 개의 테이블을 사용하는 것이 좋습니다. 이 경우 두 테이블을 모두 유지해야하지만 실제로 유지 관리가 매우 쉽습니다. isDeleted 열에 UPDATE 문을 쓸 때 다른 테이블에 INSERT INTO를 쓰고 원래 테이블에서 DELETE하십시오. 상황이 롤백 인 경우 다른 INSERT INTO 및 DELETE를 역순으로 작성하십시오. 실패한 트랜잭션이 걱정된다면이 코드를 TRANSACTION으로 감싼다.

위에서 설명한 상황에서 작은 테이블 대 큰 테이블의 장점은 무엇입니까?

  • 더 작은 테이블은 유지하기 쉽습니다.
  • 인덱스 다시 작성 작업이 훨씬 빠릅니다.
  • 아카이브 데이터를 다른 파일 그룹으로 이동하면 기본 파일 그룹의로드가 감소합니다 (모든 파일 그룹이 다른 시스템에 있음을 고려). 이렇게하면 백업 속도도 빨라집니다.
  • 더 작은 크기로 인해 통계가 자주 업데이트되며 이는 리소스 집약적입니다.
  • 인덱스의 크기가 작아집니다.
  • 테이블 크기가 작을수록 테이블 성능이 향상됩니다.

16
이러한 방법을 사용하여 외래 키를 어떻게 처리 하시겠습니까? 삭제중인 레코드를 참조하고 다른 테이블로 이동하는 다른 테이블이 1 개, 10 개 이상있을 수 있습니다!
sam360

@ sam360-그것은 큰 도전입니다. 솔직히 말해서 나는 PK와 테이블 간의 관계를 다루기 때문에 개인적으로 프로젝트에서 위의 권장 사항을 구현하지 못했습니다. 불행히도 그 기사에는 실제 사례가 없었습니다. 그것이 좋은 구현으로 밝혀졌다 있다면 ... 난 당신과 코드를 공유 할, 내 프로젝트 중 하나의 솔루션에서 일하고 있어요
Tohid

뭐라고 해요 ? 일시 삭제 대신?
유진 2015-12-20

1
@eugene-이 솔루션에 대한 특정 용어를 모릅니다. 이것은 정말로 "삭제"행이고, "아카이브"테이블 접근 방식 에서 삭제 된 레코드를 유지 하는 것입니다.
Tohid

1
나는 오라클의 파티션으로 구현 될 수있다 "다른 파일 그룹에 아카이브 데이터를 이동", 믿고, 그래서 하나 ... 장점 위에 나열된 얻을
Betlista

14

저는 NoSQL 개발자이고, 마지막 직장에서 누군가에게 항상 중요한 데이터로 작업했는데, 생성 된 당일에 실수로 삭제 된 경우 마지막 백업에서 찾을 수 없었습니다. 어제! 그런 상황에서 소프트 삭제는 항상 그날을 저장했습니다.

타임 스탬프를 사용하여 소프트 삭제를 수행하고 문서가 삭제 된 날짜를 등록했습니다.

IsDeleted = 20150310  //yyyyMMdd

매주 일요일에는 프로세스가 데이터베이스를 탐색하고 IsDeleted 현장을 . 현재 날짜와 타임 스탬프의 차이가 N 일보다 크면 문서가 영구 삭제 된 것입니다. 일부 백업에서 문서를 계속 사용할 수 있다는 점을 고려하면 안전하게 수행 할 수 있습니다.

편집하다: 이 NoSQL 사용 사례는 데이터베이스에서 생성되는 대용량 문서에 대한 것입니다. 매일 수십 또는 수백 개가 생성되지만 수천 또는 수백만 개는 아닙니다. 일반적으로 워크 플로 프로세스의 상태, 데이터 및 첨부 파일이있는 문서였습니다. 이것이 사용자가 중요한 문서를 삭제할 가능성이있는 이유입니다. 이 사용자는 관리자 권한이있는 사람이거나 문서의 소유자 일 수 있습니다.

TL; DR 내 사용 사례는 빅 데이터가 아닙니다. 이 경우 다른 접근 방식이 필요합니다.


9

내가 사용한 한 가지 패턴은 미러 테이블을 만들고 기본 테이블에 트리거를 연결하는 것이므로 모든 삭제 (및 원하는 경우 업데이트)가 미러 테이블에 기록됩니다.

이를 통해 삭제 / 변경된 레코드를 "재구성"할 수 있으며 기본 테이블에서 하드 삭제하고 "정리"상태로 유지할 수 있습니다. 또한 "실행 취소"기능을 생성 할 수 있으며 날짜, 시간도 기록 할 수 있습니다. , 미러 테이블에서 작업을 수행 한 사용자 (마녀 사냥 상황에서 매우 유용함).

다른 장점은 미러 테이블의 레코드를 포함하는 문제를 고의로 수행하지 않는 한 기본 레코드를 쿼리 할 때 실수로 삭제 된 레코드를 포함 할 가능성이 없다는 것입니다 (라이브 및 삭제 된 레코드를 표시 할 수 있음).

또 다른 장점은 미러 테이블을 독립적으로 제거 할 수 있다는 것입니다. 실제 외래 키 참조가 없어야하기 때문에 소프트 삭제를 사용하지만 여전히 다른 테이블에 대한 참조 연결이있는 기본 테이블에서 제거하는 것과 비교할 때 비교적 간단한 작업입니다.

다른 장점은 무엇입니까? -프로젝트를 진행하는 코더가 많고, 기술과 세부 수준에 대한주의가 혼합 된 데이터베이스에서 읽기를 수행하는 경우, 그중 한 명이 삭제 된 것을 포함하지 않기를 바라며 밤을 지날 필요가 없습니다. 기록 (웃음, 삭제 된 기록을 포함하지 않음 = True). 고객이 사용 가능한 현금 포지션을 과장해서 말한 다음 (즉, 거래 시스템에서와 같이) 주식을 사러가는 것과 같은 결과가 발생합니다. 초기 "오버 헤드"가 조금 더 많더라도 강력한 솔루션의 가치를 매우 빠르게 찾을 수 있습니다.

예외 :
-가이드로 사용자, 카테고리 등과 같은 "참조"데이터에 대해서는 소프트 삭제를 사용하고 "사실"유형 데이터 (예 : 트랜잭션 내역)에 대해서는 미러 테이블에 하드 삭제를 사용하십시오.


5

저는 일반적으로 논리적 삭제를 사용합니다. '삭제 된'데이터를 보관 된 테이블 (필요한 경우 검색 할 수 있음)에 간헐적으로 보관하여 애플리케이션 성능에 영향을 미치지 않을 때 잘 작동합니다.

감사를받는 경우에도 데이터가 남아 있기 때문에 잘 작동합니다. 물리적으로 삭제하면 사라집니다 !


5

저는 특히 LOB (기간 업무) 응용 프로그램이나 사용자 계정의 컨텍스트에서 논리적 삭제를 좋아합니다. 내 이유는 간단합니다. 사용자가 더 이상 시스템을 사용하지 못하도록하는 경우가 많지만 (계정이 삭제 된 것으로 표시됨) 사용자를 삭제하면 모든 작업을 잃게됩니다.

또 다른 일반적인 시나리오는 사용자가 삭제 된 후 잠시 동안 다시 생성 될 수 있다는 것입니다. 사용자가 데이터를 다시 만들지 않고 삭제하기 전의 모든 데이터를 표시하는 것이 훨씬 더 좋은 경험입니다.

일반적으로 사용자를 삭제하는 것은 사용자를 무기한 "정지"하는 것으로 생각합니다. 그들이 합법적으로 돌아와야 할 때를 알 수 없습니다.


여기서 논리적 삭제 대신 계정 활성화 / 비활성화와 같은 것을 사용해야하지 않습니까? @ jon-dewees
Eagle_Eye

4

나는 거의 항상 소프트 삭제하고 그 이유는 다음과 같습니다.

  • 고객이 요청하면 삭제 된 데이터를 복원 할 수 있습니다. 소프트 삭제로 더 행복한 고객. 백업에서 특정 데이터를 복원하는 것은 복잡합니다.
  • isdeleted모든 곳을 확인 하는 것은 문제가되지 않으므로 userid어쨌든 확인해야 합니다 (데이터베이스에 여러 사용자의 데이터가 포함 된 경우). 이 두 가지 검사를 별도의 함수에 배치 (또는보기 사용)하여 코드로 검사를 시행 할 수 있습니다.
  • 우아한 삭제. 삭제 된 콘텐츠를 처리하는 사용자 또는 프로세스는 다음 새로 고침을 수행 할 때까지 계속해서 "볼"것입니다. 프로세스가 갑자기 삭제 된 일부 데이터를 처리하는 경우 매우 바람직한 기능입니다.
  • 동기화 : 데이터베이스와 모바일 앱 간의 동기화 메커니즘을 설계해야하는 경우 소프트 삭제를 훨씬 쉽게 구현할 수 있습니다.

@Jim은 데이터를 데이터베이스에 저장하는 것은 불법이 아닙니다. 고객이 자신의 데이터를 삭제하라고 말한 후에도 기록을 보관하는 것은 불법입니다. 소프트 삭제는 GDPR과 완벽하게 호환됩니다. 요청시 빈 데이터로 현명한 데이터를 덮어 씁니다. 또한 사용자가 레코드를 삭제하는 경우 나중에 작업을 실행 취소하거나 어떻게 든 데이터를 복원 할 수 있습니다. 그렇다고 데이터가 데이터베이스에서 완전히 사라지
기를

3

Re : "안전한가요?" -그것은 당신이 의미하는 바에 달려 있습니다.

물리적 삭제를 수행 하면 누군가가 삭제 된 데이터를 찾지 못하도록 방지 할 수 있습니다. 그렇습니다. 이는 다소 사실입니다. 지워야하는 민감한 데이터를 물리적으로 삭제하는 것이 더 안전합니다. 이는 데이터베이스에서 영구적으로 삭제된다는 것을 의미하기 때문입니다. (그러나 백업, 트랜잭션 로그 또는 전송중인 기록 된 버전 (예 : 패킷 스니퍼)과 같이 문제가되는 데이터의 다른 복사본이있을 수 있습니다. 데이터베이스에서 삭제하지 않기 때문에 다른 곳에 저장되지 않았는지 확인하십시오.)

논리적 삭제를 수행 하면 데이터를 잃지 않기 때문에 데이터가 더 안전 하다는 의미도 마찬가지입니다. 이는 감사 시나리오에 유용합니다. 나는 데이터가 생성되면, 그것은 결코거야 기본적인 사실을 인정하기 때문에이 방법을 설계하는 경향이 정말 (그것도 말하자면, 인터넷 검색 엔진에 의해 캐시되는 능력을 가지고 특히 경우) 멀리 갈합니다. 물론 실제 감사 시나리오에서는 논리적 삭제 일뿐만 아니라 변경 시간 및 변경 한 행위자와 함께 업데이트도 기록되어야합니다.

데이터를 보지 말아야 할 사람의 손에 들어 가지 않는다는 뜻이라면 그것은 전적으로 애플리케이션과 보안 구조에 달려 있습니다. 그런 점에서 논리적 삭제는 데이터베이스의 다른 어떤 것보다 안전하지 않습니다.


3

많은 오류에 노출되어 있기 때문에 논리적 삭제에 강력히 동의하지 않습니다.

먼저 각 쿼리는 IsDeleted 필드를 처리해야하며 복잡한 쿼리에서는 오류 가능성이 높아집니다.

둘째, 성능 : 3 개만 활성화 된 100000 recs가있는 테이블을 상상해보십시오. 이제이 숫자를 데이터베이스 테이블에 곱하십시오. 또 다른 성능 문제는 이전 (삭제 된 레코드)이있는 새 레코드와의 충돌 가능성입니다.

내가 볼 수있는 유일한 장점은 기록의 역사이지만,이 결과를 달성하기 위해 다른 방법은 당신이 정보를 저장할 수있는 로그 테이블을 만들 수 있습니다 예를 들어,이 있습니다 : TableName,OldValues,NewValues,Date,User,[..]여기서 *Values할 수 있습니다 varchar이 양식에 내용을 쓰기 fieldname : value; [..] 또는 정보를 xml.

이 모든 것은 코드 또는 트리거를 통해 달성 할 수 있지만 모든 기록이있는 테이블 은 하나 뿐입니다 . 또 다른 옵션은 지정된 데이터베이스 엔진이 변경 추적에 대한 기본 지원인지 확인하는 것입니다. 예를 들어 SQL Server 데이터베이스에는 SQL 추적 데이터 변경이 있습니다.


3

이전 기록을 유지하기 위해 일시 ​​삭제를 수행했습니다. 사용자가 생각만큼 자주 오래된 기록을 보지 않는다는 것을 깨달았습니다. 사용자가 오래된 기록을보고 싶다면 아카이브 또는 감사 테이블에서 볼 수 있습니다. 그렇죠? 그렇다면 일시 삭제의 장점은 무엇입니까? 더 복잡한 쿼리 문 등으로 이어집니다.

다음은 더 이상 소프트 삭제를하지 않기로 결정하기 전에 구현 한 것입니다.

  1. 감사를 구현하여 모든 활동 (추가, 편집, 삭제)을 기록합니다. 감사에 연결된 외래 키가 없는지 확인하고이 테이블이 보안되어 있고 관리자 외에는 아무도 삭제할 수 없는지 확인하십시오.

  2. "트랜잭션 테이블"로 간주되는 테이블을 식별합니다.이 테이블은 오랫동안 보관 될 가능성이 높고 사용자가 과거 레코드 또는 보고서를보고 싶어 할 가능성이 높습니다. 예를 들면 다음과 같습니다. 구매 거래. 이 테이블은 마스터 테이블의 ID (예 : dept-id)를 유지해야 할뿐만 아니라 이름 (예 : dept-name) 또는보고에 필요한 기타 필드와 같은 추가 정보도 유지해야합니다.

  3. 마스터 테이블의 "활성 / 비활성"또는 "활성화 / 비활성화"또는 "숨기기 / 표시"레코드를 구현합니다. 따라서 사용자는 레코드를 삭제하는 대신 마스터 레코드를 비활성화 / 비활성화 할 수 있습니다. 이 방법이 훨씬 안전합니다.

내 2 센트 의견.


2

참조 무결성이 어려운 경우 논리적 삭제.

테이블 데이터의 시간적 측면이있을 때 수행하는 것이 올바른 생각입니다 (유효한 FROM_DATE-TO_DATE).

그렇지 않으면 데이터를 감사 테이블로 이동하고 레코드를 삭제합니다.

긍정적 인 측면에서는:

롤백하는 더 쉬운 방법입니다 (가능한 경우).

특정 시점의 상태를 쉽게 알 수 있습니다.


2

무언가의 기록을 보관하려는 경우 (예 : @Jon Dewees가 언급 한 사용자 계정) 상당히 표준입니다. 그리고 사용자가 삭제 취소를 요청할 가능성이 높다면 확실히 좋은 생각입니다.

쿼리에서 삭제 된 레코드를 필터링하는 논리가 지저분 해지고 쿼리를 복잡하게 만드는 논리가 걱정된다면 필터링을 수행하는 뷰를 빌드하고 이에 대한 쿼리를 사용할 수 있습니다. 보고 솔루션 등에서 이러한 레코드의 유출을 방지합니다.


2

응답해야 할 시스템 설계 이상의 요구 사항이 있습니다. 기록 보존에 대한 법적 또는 법적 요건은 무엇입니까? 행과 관련된 항목에 따라 데이터가 '일시 중지'된 후 일정 기간 동안 보관되어야하는 법적 요구 사항이있을 수 있습니다.

반면에 레코드가 '삭제'되면 진정으로 취소 불가능하게 삭제되어야한다는 요구 사항이있을 수 있습니다. 결정을 내리기 전에 이해 관계자와 이야기하십시오.


2

동기화에 의존하는 모바일 앱은 물리적 삭제가 아닌 논리적 삭제를 사용할 수 있습니다. 서버는 레코드가 삭제 (표시)되었음을 클라이언트에 알릴 수 있어야하며 레코드가 물리적으로 삭제 된 경우에는 불가능할 수 있습니다.


1

그들은 캐스케이드 기능과 같은 것들을 쓸모 없게 만들어야하기 때문에 데이터베이스가 작동하도록하지 않습니다.

삽입과 같은 간단한 것의 경우 다시 삽입하면 그 뒤에있는 코드가 두 배가됩니다.

단순히 삽입 할 수는 없습니다. 대신 존재를 확인하고 이전에 존재하지 않는 경우 삽입해야하며, 존재하는 경우 삭제 플래그를 업데이트하는 동시에 다른 모든 열을 새 값으로 업데이트해야합니다. 이는 부정확 한 감사 로그를 유발하는 새로운 삽입이 아니라 데이터베이스 트랜잭션 로그에 대한 업데이트로 간주됩니다.

테이블이 중복 데이터로 가득 차기 때문에 성능 문제가 발생합니다. 특히 독특함으로 인해 인덱싱에 혼란을 겪습니다.

나는 논리적 삭제를 좋아하지 않습니다.


1

Tohid의 의견에 답하기 위해 우리는 기록의 역사를 유지하고 싶었던 것과 같은 문제에 직면했고 또한 우리가 is_deleted열 을 원하는지 여부를 확신 하지 못했습니다.

나는 우리의 파이썬 구현과 비슷한 사용 사례에 대해 이야기하고 있습니다.

우리는 발생 https://github.com/kvesteri/sqlalchemy-continuum 하여 해당 테이블에 대한 테이블을 버전 얻을 수있는 가장 쉬운 방법이다. 최소한의 코드 라인과 추가, 삭제 및 업데이트 기록을 캡처합니다.

이것은 is_deleted컬럼 이상의 역할을합니다 . 이 항목에서 발생한 일을 확인하기 위해 항상 버전 테이블을 역 참조 할 수 있습니다. 항목이 삭제, 업데이트 또는 추가되었는지 여부.

이렇게하면 is_deleted열 이 전혀 필요하지 않았고 삭제 기능이 매우 간단했습니다. 이렇게하면 is_deleted=FalseAPI 에 표시하는 것을 기억할 필요가 없습니다 .


0

소프트 삭제는 데이터가 더 관련성이있을 때 대부분의 응용 프로그램에서 따르는 프로그래밍 방식입니다. 최종 사용자의 실수로 인한 삭제가 치명적일 수있는 금융 애플리케이션의 경우를 고려하십시오. 소프트 삭제가 관련이있는 경우입니다. 소프트 삭제에서 사용자는 레코드에서 데이터를 실제로 삭제하는 것이 아니라 IsDeleted가 true로 플래그 지정됩니다 (일반적인 규칙에 따라).

EF 6.x 또는 EF 7 이상에서는 Softdelete가 속성으로 추가되었지만 당분간 사용자 지정 속성을 만들어야합니다.

데이터베이스 디자인에 SoftDelete를 강력히 권장하며 프로그래밍 실습을위한 좋은 규칙입니다.


0

대부분의 경우 소프트 삭제는 일부 데이터를 노출하고 싶지 않지만 기록적인 이유로 보관해야하기 때문에 사용됩니다 (제품이 중단 될 수 있으므로 제품에 대한 새로운 트랜잭션을 원하지 않지만 계속 작업해야합니다. 판매 거래 내역). 그런데 일부는이를 처리하기 위해 제품을 참조하는 대신 판매 거래 데이터의 제품 정보 값을 복사하고 있습니다.

실제로 표시 / 숨김 또는 활성 / 비활성 기능에 대한 단어 변경처럼 보입니다. 그것이 비즈니스 세계에서 "삭제"의 의미이기 때문입니다. 터미네이터는 사람을 삭제할 수 있지만 보스는 그냥 해고한다고 말하고 싶습니다.

이 관행은 매우 일반적인 패턴이며 많은 이유로 많은 응용 프로그램에서 사용됩니다. 이것이 이것을 달성하는 유일한 방법이 아니기 때문에 수천 명의 사람들이 그것이 훌륭하거나 헛소리라고 말하고 둘 다 꽤 좋은 주장을 할 것입니다.

보안의 관점에서 SoftDelete는 감사 작업을 대체하지 않으며 백업 작업도 대체하지 않습니다. "두 백업 케이스 간의 삽입 / 삭제"가 두렵다면 전체 또는 대량 복구 모델에 대해 읽어야합니다. SoftDelete가 복구 프로세스를 더 간단하게 만들 수 있음을 인정합니다.

귀하의 요구 사항을 알고 있습니다.


0

대안을 제공하기 위해 MobiLink를 통해 업데이트하는 원격 장치를 사용하는 사용자가 있습니다. 서버 데이터베이스에서 레코드를 삭제하면 해당 레코드는 클라이언트 데이터베이스에서 삭제 된 것으로 표시되지 않습니다.

그래서 우리는 둘 다합니다. 우리는 고객과 협력하여 데이터를 복구 할 수있는 기간을 결정합니다. 예를 들어, 일반적으로 고객과 제품은 고객이 삭제해야한다고 말할 때까지 활성 상태이지만 판매 내역은 13 개월 동안 만 유지 된 다음 자동으로 삭제됩니다. 클라이언트는 삭제 된 고객 및 제품을 2 개월 동안 유지하고 기록은 6 개월 동안 유지하려고 할 수 있습니다.

따라서 이러한 매개 변수에 따라 논리적으로 삭제 된 항목을 표시하는 스크립트를 밤새 실행하고 2/6 개월 후 오늘 논리적으로 삭제 된 것으로 표시된 모든 항목은 영구 삭제됩니다.

스마트 폰과 같이 메모리가 제한된 클라이언트 장치에 방대한 데이터베이스를 보유하는 것보다 데이터 보안이 중요하지 않습니다. 4 년 동안 일주일에 두 번 200 개의 제품을 주문하는 고객은 81,000 개 이상의 라인을 보유하게되며이 중 75 %는 고객이 보더라도 상관하지 않습니다.


0

그것은 모두 시스템의 사용 사례와 데이터에 달려 있습니다.

예를 들어, 정부 규제 시스템 (예 : 품질 시스템의 일부로 간주되고 전자 기록에 대한 FDA 지침을 따라야하는 제약 회사의 시스템)에 대해 이야기하고 있다면 하드 삭제를하지 않는 것이 좋습니다! FDA의 감사관이 들어 와서 제품 번호 ABC-123과 관련된 시스템의 모든 기록을 요청할 수 있으며 모든 데이터를 더 잘 사용할 수 있습니다. 비즈니스 프로세스 소유자가 시스템이 앞으로 새 레코드에 제품 번호 ABC-123을 사용하는 것을 허용해서는 안된다고 말하면, 대신 소프트 삭제 방법을 사용하여 기록 데이터를 유지하면서 시스템 내에서 "비활성"상태로 만듭니다.

그러나 시스템과 데이터에 "북극의 날씨 추적"과 같은 사용 사례가있을 수 있습니다. 아마도 당신은 매시간 한 번씩 체온을 측정하고 하루가 끝나면 일일 ​​평균을 집계 할 수 있습니다. 집계 후에는 시간별 데이터가 더 이상 사용되지 않을 수 있으며 집계를 만든 후에는 시간별 판독 값을 영구 삭제해야합니다. (이것은 구성되고 사소한 예입니다.)

요점은 모든 것이 시스템과 데이터의 사용 사례에 달려 있으며 순수하게 기술적 인 관점에서 내려진 결정이 아니라는 것입니다.


0

잘! 모두가 말했듯이 상황에 따라 다릅니다.

UserName 또는 EmailID와 같은 열에 인덱스가 있고 동일한 UserName 또는 EmailID가 다시 사용될 것으로 기대하지 않습니다. 소프트 삭제로 갈 수 있습니다.

즉, SELECT 작업이 기본 키를 사용하는지 항상 확인하십시오. SELECT 문이 기본 키를 사용하는 경우 WHERE 절과 함께 플래그를 추가해도 큰 차이가 없습니다. 예를 들어 보겠습니다 (Pseudo) :

테이블 사용자 (UserID [기본 키], EmailID, IsDeleted)

SELECT * FROM Users where UserID = 123456 and IsDeleted = 0

이 쿼리는 UserID 열에 기본 키가 있으므로 성능면에서 차이가 없습니다. 처음에는 PK를 기반으로 테이블을 스캔 한 후 다음 조건을 실행합니다.

일시 삭제가 전혀 작동하지 않는 경우 :

주로 모든 웹 사이트에 가입하면 EmailID를 고유 ID로 사용합니다. Facebook, G +와 같은 웹 사이트에서 EmailID가 사용되면 다른 사람이 사용할 수 없습니다.

사용자가 웹 사이트에서 자신의 프로필을 삭제하고 싶은 날이 왔습니다. 이제 논리적으로 삭제하면 해당 사용자는 다시 등록 할 수 없습니다. 또한 동일한 EmailID를 사용하여 다시 등록한다고해서 전체 기록이 복원되는 것은 아닙니다. 누구나 알고 있습니다. 삭제는 삭제를 의미합니다. 이러한 시나리오에서는 물리적 삭제를해야합니다. 그러나 계정의 전체 내역을 유지하려면 항상 이러한 레코드를 보관 테이블 또는 삭제 된 테이블에 보관해야합니다.

예, 외국 테이블이 많은 상황에서는 처리가 상당히 번거 롭습니다.

또한 소프트 / 논리적 삭제는 테이블 크기를 증가시켜 인덱스 크기를 증가 시킨다는 점에 유의하십시오.


0

이미 다른 게시물에서 답변 했습니다 . 그러나 내 대답은 여기의 질문에 더 적합하다고 생각합니다.

: 소프트 삭제에 대한 나의 실용적인 솔루션은 다음과 같은 열이있는 새 테이블을 작성하여 보관한다 original_id, table_name, payload, (및 선택적 기본 키`ID).

original_id삭제 된 레코드의 원래 ID는 어디에 있고 삭제 된 레코드 table_name 의 테이블 이름 ( "user"귀하의 경우) payload은 삭제 된 레코드의 모든 열에서 JSON 문자열 문자열입니다.

또한 original_id후자의 데이터 검색을 위해 열에 인덱스를 만드는 것이 좋습니다 .

이러한 방식으로 데이터를 보관합니다. 이러한 이점이 있습니다.

  • 기록의 모든 데이터를 추적
  • 삭제 된 레코드의 테이블 구조에 관계없이 모든 테이블에서 레코드를 보관할 수있는 위치는 한 곳뿐입니다.
  • 원본 테이블의 고유 인덱스에 대한 걱정 없음
  • 원본 테이블에서 외부 인덱스를 확인할 걱정 없음
  • WHERE삭제를 확인할 모든 쿼리에 더 이상 절이 없습니다.

이미 토론입니다 여기 소프트 삭제 실제로 좋은 생각이 아니다 이유를 설명. 일시 삭제는 레코드 계산과 같은 향후 잠재적 인 문제를 야기합니다.


나는 데이터 삭제의 모든 방법에 블로그 게시물을 작성했습니다 transang.me/database-design-practice-soft-deletion-to
transang

0

Adventage는 데이터 보존 / 영구입니다. 장애는 상당한 양의 소프트 삭제가있는 테이블에서 데이터를 쿼리하거나 검색 할 때 성능이 저하되는 것입니다. 우리의 경우 우리는이 둘의 조합을 사용 : 다른 사람이 이전 답변에서 언급 한 것처럼, 우리를 soft-delete users/clients/customers예를 들어,과 hard-deleteitems/products/merchandise꿀벌 keept 할 필요가 없습니다 중복 레코드가 테이블.


0

경우에 따라 다르므로 다음을 고려하십시오.

일반적으로 레코드를 "소프트 삭제"할 필요가 없습니다. 간단하고 빠르게 유지하십시오. 예를 들어 더 이상 사용할 수없는 제품을 삭제할 수 있으므로 앱 전체 (개수, 제품 목록, 추천 제품 등)에서 제품이 일시 삭제되지 않았는지 확인할 필요가 없습니다.

그러나 데이터웨어 하우스 모델에서 "일시 삭제"를 고려할 수 있습니다. 예 : 삭제 된 제품에 대한 이전 영수증을보고 있습니다. *

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.