데이터베이스 동기화 및 일시 삭제 시나리오에서 삭제 표시 테이블과 삭제 된 플래그


17

클라이언트 동기화 요구를 위해 삭제 된 항목을 추적해야합니다.

일반적으로 삭제 표시 테이블 및 행을 서버 데이터베이스에서 삭제 한 시점을 추적하는 트리거 를 추가하는 것이 좋습니다. 기본적으로 삭제 된 항목의 데이터를 사용하여 삭제 표시 테이블에 새 행을 추가하거나 항목을 원래 테이블 을 삭제하고 행이 삭제되었음을 표시하고 삭제가 발생했을 때 추적 할 다른 열을 표시하기 위해 일반적으로 비트 유형의 열과 함께 삭제 된 플래그 를 지정합니까?

답변:


17

일반적으로 특정 요구 사항을 파악하고 대부분의 상황에서 가장 적합한 것을 기반으로 설계 결정을 내리지 않는 것이 좋습니다. 어느 것이 바람직 할 수있다. 다음은 수집해야 할 사항입니다.

  • 삭제는 얼마나 빠릅니까?
  • 삭제 취소는 얼마나 빠릅니까?
  • 삭제 된 데이터는 얼마나 자주 쿼리되며 삭제되지 않은 데이터로 쿼리됩니까?
  • 삭제 된 데이터에 대한 쿼리는 얼마나 빠릅니까?
  • 삭제 된 항목이나 변경 사항 만 보존해야합니까?
  • 기본 테이블의 테이블 / 인덱스를 작게 유지해야합니까?
  • 데이터베이스 플랫폼에서 어떤 파티션 및 / 또는 변경 추적 기술을 사용할 수 있습니까?
  • 사용 가능한 디스크 공간이 얼마나됩니까?
  • 삭제가 즉시 또는 일괄 작업으로 수행됩니까?

다른 시스템 요구 사항 사이의 거래 문제입니다. 빠른 삭제 / 삭제 취소가 필요한 경우 플래그가 선호되지만 삭제 된 항목과 기본 테이블에 대한 빠른 쿼리가 필요하고 변경 유형을 추적해야 할 경우 삭제 표시 방식이 보다 나은.
Lorenzo Polidori

맞아요. 다른 옵션이 바람직한 경우도 있습니다. 예를 들어, 24 시간 동안 사용 가능한 소프트 삭제 만 필요한 경우 Oracle에서 보장 된 실행 취소 보존 시간을 설정 한 다음 플래시백 쿼리를 사용하여 삭제 된 데이터를 볼 수 있습니다.
레이 리펠

5

두 가지 방법을 의도적으로 결합해야 할 수도 있습니다. 왜 ???

해당 테이블을 사용합시다 (MySQL- 방언)

CREATE TABLE mydata
(
    id int not null auto_increment
    firstname varchar(16) not null,
    lastname varchar(16) not null,
    zipcode char(5) not null,
    ...
    deleted tinyint not null default 0
    KEY (deleted,id),
    KEY (deleted,lastname,firstname,id),
    KEY (deleted,zipcode,id),
    KEY (lastname,firstname),
    KEY (zipcode),
    PRIMARY KEY (id)
);

PRIMARY KEY를 제외하고 모든 색인 앞에는 deleted플래그 가 붙어야 하고으로 끝나야합니다 id.

삭제 표시 테이블을 만들어 봅시다

CREATE TABLE mytomb SELECT id FROM mydata WHERE 1=2;
ALTER TABLE mytomb ADD PRIMARY KEY (id);

테이블에 이미 deleted플래그가 있으면 툼 스톤 테이블을 채울 수 있습니다

INSERT INTO mytomb SELECT id FROM mydata WHERE deleted = 1;

이제 데이터와 묘비가 준비되었습니다. 삭제는 어떻게 수행합니까?

07305 우편 번호의 모든 사람을 삭제한다고 가정 해 봅시다. 다음을 실행하십시오.

INSERT IGNORE INTO mytomb SELECT id FROM mydata WHERE deleted=0 AND zipcode='07305';
UPDATE mydata SET deleted=1 WHERE deleted=0 AND zipcode='07305';

좋아, 이것은 당신이 그것을 보는 어느 쪽이든 많은 오버 헤드처럼 보입니다.

이제 삭제 된 모든 데이터를 보시겠습니까? 두 가지 방법이 있습니다.

  • SELECT * FROM mydata WHERE deleted=1;
  • SELECT B.* FROM mytomb A INNER JOIN mydata B USING (id);

mytomb의 ID 수가 mydata의 행 수의 5 %보다 큰 경우 전체 테이블 스캔입니다. 그렇지 않으면 각 행을 조회하는 인덱스 스캔. 이러한 점에서 벤치 마크에 유의하십시오. 설명 계획을 찾아보십시오.

이제 우편 번호 07304의 모든 사람을 보시겠습니까? 두 가지 방법이 있습니다.

  • SELECT * FROM mydata WHERE deleted=1 AND zipcode='07304';
  • SELECT A.* FROM mydata A LEFT JOIN mytomb B USING (id) WHERE B.id IS NULL AND A.zipcode='07304'

대량 삭제는 어떻습니까? 두 가지 방법이 있습니다.

  • DELETE FROM mydata WHERE deleted=1;
  • DELETE B.* FROM mytomb A INNER JOIN mydata B USING (id); DELETE FROM mytomb;

결론

이제 두 가지 방법을 모두 유지한다고 말하지는 않습니다. 시간이 지남에 따라이 작업을 수행하면 전반적인 운영 측면에서 어떤 방법이 더 빠릅니다. 라이브 데이터 쿼리, 삭제 된 데이터 쿼리 및 대량 삭제에 가장 적합한 벤치 마크를 결정해야합니다.


두 기술을 지속적으로 사용하는 것이 유리합니까? 아니면 성능을 평가하기 위해 병렬로 사용하고 제안하는 것이 좋습니다.
모든 거래의 존
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.