문제

현재 프로젝트를 진행 중이며 대부분의 사용자(사용자 역할)에 대해 소프트 삭제를 구현해야 합니다.우리는 데이터베이스의 각 테이블에 "is_deleted='0'" 필드를 추가하고 특정 사용자 역할이 특정 레코드에서 삭제 버튼을 누르면 이를 '1'로 설정하기로 결정했습니다.

향후 유지 관리를 위해 각 SELECT 쿼리에는 is_deleted='1'인 레코드가 포함되지 않도록 해야 합니다.

일시 삭제를 구현하기 위한 더 나은 솔루션이 있습니까?

업데이트:또한 응용 프로그램 데이터베이스 내의 모든 테이블/필드에 대한 변경 사항(필드, 이전 값, 새 값, 시간, 사용자, IP)을 추적하는 감사 데이터베이스가 있다는 점에도 유의해야 합니다.

도움이 되었습니까?

해결책

다음을 포함하는 뷰에 대해 모든 쿼리를 수행할 수 있습니다. WHERE IS_DELETED='0' 절.

다른 팁

나는 "Rails way"쪽으로 기댈 것입니다. deleted_at 다음을 포함하는 열 삭제가 발생한 날짜/시간.그러면 삭제에 대한 약간의 무료 메타데이터를 얻을 수 있습니다.당신을 위해 SELECT 그냥 행을 가져와 WHERE deleted_at IS NULL

is_deleted 열은 상당히 좋은 접근 방식입니다.Oracle에 있는 경우 성능을 더욱 높이려면 다음에 목록 파티션을 생성하여 테이블을 파티셔닝하는 것이 좋습니다. is_deleted 열.그런 다음 삭제된 행과 삭제되지 않은 행은 물리적으로 다른 파티션에 있지만 사용자에게는 투명합니다.

결과적으로 다음과 같은 쿼리를 입력하면

SELECT * FROM table_name WHERE is_deleted = 1

그러면 Oracle은 '파티션 정리'를 수행하고 적절한 파티션만 조사합니다.내부적으로 파티션은 다른 테이블이지만 사용자에게는 투명합니다.분할 여부에 관계없이 전체 테이블에서 선택할 수 있습니다.하지만 Oracle은 쿼리할 수 있습니다. 필요한 파티션만.예를 들어 1000개의 행이 있다고 가정해 보겠습니다. is_deleted = 0 100000 행 is_deleted = 1, 테이블을 분할합니다. is_deleted.이제 조건을 포함하면

WHERE ... AND IS_DELETED=0

그러면 Oracle은 1000개의 행이 있는 파티션만 스캔합니다.테이블이 분할되지 않은 경우 101000개 행(두 파티션 모두)을 스캔해야 합니다.

테이블이 크고 성능이 문제인 경우 언제든지 '삭제된' 레코드를 삭제 시간, 레코드를 삭제한 사람 등과 같은 추가 정보가 있는 다른 테이블로 이동할 수 있습니다.

그렇게 하면 기본 테이블에 다른 열을 추가할 필요가 없습니다.

안타깝게도 최선의 대응은 소프트 삭제를 통해 달성하려는 작업과 이를 구현하는 데이터베이스에 따라 달라집니다.

SQL Server에서 가장 좋은 솔루션은 SMALLDATETIME 또는 DATETIME 유형(필요한 세분성에 따라 다름)의 delete_on/deleted_at 열을 사용하고 해당 열을 Null 허용으로 만드는 것입니다.SQL Server에서 행 헤더 데이터에는 테이블의 각 열에 대한 NULL 비트마스크가 포함되어 있으므로 열에 저장된 값을 확인하는 것보다 IS NULL 또는 IS NOT NULL을 수행하는 것이 약간 더 빠릅니다.

데이터의 양이 많은 경우 데이터베이스 자체를 통해 또는 두 개의 별도 테이블(예:제품 및 ProductHistory) 또는 인덱싱된 뷰를 통해.

일반적으로 is_deleted, is_archive 등과 같은 플래그 필드는 하나의 의미만 전달하므로 피합니다.nullable delete_at, archived_at 필드는 자신과 애플리케이션을 상속하는 사람에게 추가적인 수준의 의미를 제공합니다.그리고 저는 전염병과 같은 비트마스크 분야를 피합니다. 의미를 파악하려면 비트마스크가 어떻게 만들어졌는지 이해해야 하기 때문입니다.

이는 필요한 정보와 지원하려는 워크플로에 따라 다릅니다.

당신은 다음을 할 수 있기를 원하십니까?

  • (삭제되기 전) 어떤 정보가 있었는지 아시나요?
  • 언제 삭제됐는지 알아?
  • 누가 삭제했는지 알아?
  • 그들이 그것을 삭제했을 때 어떤 능력으로 행동했는지 아십니까?
  • 기록 삭제를 취소할 수 있나요?
  • 언제 삭제 취소되었는지 알 수 있나요?
  • 등.

기록이 4번 삭제되었다가 삭제 취소된 경우, 현재 삭제되지 않은 상태라는 것만 알면 충분합니까, 아니면 그 사이에 무슨 일이 일어났는지(연속적인 편집 내용 포함) 알 수 있기를 원합니까? 삭제!)?

고유성 제약 조건 위반을 일으키는 일시 삭제된 레코드에 주의하세요.DB에 고유 제약 조건이 있는 열이 있는 경우 이전에 일시 삭제된 레코드로 인해 레코드를 다시 만드는 데 방해가 되지 않도록 주의하세요.

주기를 생각해 보세요.

  1. 사용자 생성(로그인=JOE)
  2. 일시 삭제(삭제된 열을 null이 아닌 항목으로 설정)
  3. (재) 사용자를 생성합니다(login=JOE).오류.로그인=JOE는 이미 사용 중입니다.

login=JOE가 이미 일시 삭제된 행에 있기 때문에 두 번째 만들기에서는 제약 조건 위반이 발생합니다.

일부 기술:1.삭제된 레코드를 새 테이블로 이동합니다.2.로그인 및 delete_at 타임스탬프 열 전체에 고유성 제약 조건을 설정하세요.

내 의견은 새 테이블로 이동하는 것에 대해 +1입니다.모든 쿼리에서 * 및 delete_at = null *을 유지하려면 많은 훈련이 필요합니다 (모든 개발자를 위해)

Jim이 말한 것처럼 삭제된 데이터를 다른 테이블로 옮기고 삭제 시기, 이유, 삭제자에 대한 기록을 갖고 있으면 확실히 더 나은 성능을 얻을 수 있습니다.

첨가 where deleted=0 모든 쿼리를 실행하면 속도가 크게 느려지고 테이블에 있는 인덱스의 사용이 방해를 받습니다.가능하면 테이블에 "플래그"를 두지 마십시오.

프로젝트에서 내가 사용하는 것은 statusInd tinyint null default 0 열을 비트 마스크로 사용하여 데이터 관리 (삭제, 아카이브, 복제, 복원 등)를 수행 할 수 있습니다.이를 뷰에서 사용하면 소비 애플리케이션에 대한 데이터 배포, 게시 등을 수행할 수 있습니다.뷰와 관련하여 성능이 문제인 경우 작은 팩트 테이블을 사용하여 이 정보를 지원하고 팩트를 삭제하고 관계를 삭제하고 호출된 삭제를 허용합니다.

확장성이 뛰어나고 데이터 공간을 매우 작게 유지하는 데이터 중심입니다. 실시간 문제가 있는 350gb+ dbs의 핵심입니다.대안, 테이블, 트리거를 사용하면 필요에 따라 작동할 수도 있고 작동하지 않을 수도 있는 약간의 오버헤드가 있습니다.

SOX 관련 감사에서는 귀하의 사례에 도움이 되기 위해 하나 이상의 필드가 필요할 수 있지만 이것이 도움이 될 수 있습니다.즐기다

어떤 제품인지는 언급하지 않았지만 SQL Server 2008과 postgresql(및 기타 제품)에서는 필터링된 인덱스를 생성할 수 있으므로 is_deleted=0인 커버 인덱스를 생성하여 이 특정 접근 방식의 단점 중 일부를 완화할 수 있습니다. .

나는 상태 열을 유지하는 것을 선호하므로 이를 여러 가지 다른 구성에 사용할 수 있습니다.게시됨, 비공개, 삭제됨, 승인 필요...

is_deleted=0을 확인하는 뷰, 함수, 프로시저를 사용하세요.나중에 다른 이유로 테이블을 변경해야 하는 경우를 대비해 테이블에서 직접 선택하지 마세요.

더 큰 테이블의 경우 is_deleted 열을 색인화합니다.

이미 감사 추적이 있으므로 삭제 날짜를 추적하는 것은 중복됩니다.

다른 스키마를 생성하고 데이터 스키마에 모두 부여합니다.각각의 모든 쿼리에 삭제되지 않은 행만 선택할 수 있는 조건자가 추가되도록 새 스키마에 VPD를 구현합니다.http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/cmntopc.htm#CNCPT62345

@AdditionalCriteria("this.status <> '삭제됨'")

이것을 @entity 위에 놓으십시오.

http://wiki.eclipse.org/EclipseLink/Examples/JPA/SoftDelete

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top