2009-09-25 3 views
3

테이블 감사 방법에 대한 주제가 최근에 토론에서 나타났습니다 ... 그래서 나는이 문제에 접근하는 가장 좋은 방법이 무엇인지에 대한 여러분의 의견을 좋아합니다. 우리는 DBA가 각자 올바른 방법이라고 믿었던 것처럼 이전 DBA와 마찬가지로 두 가지 방식 (모두 좋지 않음)을 데이터베이스에 혼합했습니다. 그래서 우리는 어떤 모델을 따라갈 필요가 있습니다.감사 트리거 : INSERTED 또는 DELETED 시스템 테이블 사용

CREATE TABLE dbo.Sample(
Name VARCHAR(20), 
... 
... 
Created_By VARCHAR(20), 
Created_On DATETIME, 
Modified_By VARCHAR(20), 
Modified_On DATETIME 
) 

CREATE TABLE dbo.Audit_Sample(
Name VARCHAR(20), 
... 
... 
Created_By VARCHAR(20), 
Created_On DATETIME, 
Modified_By VARCHAR(20), 
Modified_On DATETIME 
Audit_Type VARCHAR(1) NOT NULL 
Audited_Created_On DATETIME 
Audit_Created_By VARCHAR(50) 
) 

접근 1 : 스토어, 감사 테이블 기본 테이블에서 삭제 교체, 레코드 만/년 (사용하여 시스템 테이블 DELETED). 따라서 주 테이블의 각 UPDATE 및 DELETE에 대해 'Audit_Type'열이 'U'(UPDATE의 경우) 또는 'D'(DELETE의 경우) 인 감사 테이블에 INSERTED됩니다.

INSERT 감사하지 않습니다. 현재 버전의 레코드의 경우 항상 주 테이블을 쿼리합니다. 그리고 히스토리에 대해 감사 테이블을 쿼리합니다.

장점 : 이전 버전의 레코드를 저장하는 데 유용합니다. : 특정 레코드의 기록을 알아야 할 경우 주 테이블과 감사 테이블을 조인해야합니다.

Appraoch 2 : (시스템 테이블 INSERTED를 사용하여) 주 테이블로 이동하는 모든 레코드를 감사 테이블에 저장하십시오.

주 테이블에 INSERTED/UPDATED/DELETED 인 각 레코드는 감사 테이블에도 저장됩니다. 따라서 새 레코드를 삽입하면 감사 테이블에도 삽입됩니다. 갱신되면 INSERTED 테이블의 새 버전이 감사 테이블에 저장됩니다. 삭제되면 이전 버전 (DELETED에서) 테이블이 감사 테이블에 저장됩니다.

장점 : 특정 기록의 기록을 알아야하는 경우 한 곳에서 모든 것을 확인할 수 있습니다.

여기에 모두 나열하지 않았지만 각 접근법에는 장단점이 있습니까?

답변

4

내가 함께 갈 것 :

Appraoch 2 : 스토어, 감사 테이블에서, (사용 INSERTED 시스템 테이블) 기본 테이블 로가는 모든 레코드.

항목 당 하나 이상의 행이 실제로 DB를 죽일 것입니까? 이렇게하면 완전한 역사를 함께 할 수 있습니다.

당신이 행을 제거하는 경우 (범위를 모든 X 일보다 오래된) 뭔가를 변경하거나하지 않은 경우 당신은 여전히 ​​알 수 있습니다 : 감사 행 (제거하지 않음) 존재

  • 경우 행이 있는지 볼 수 있습니다 문제가 변경되었습니다. 그리고 밖으로 제거 : 더 감사 행 (모두 제거되었다) (어떤 변화가 완전히 새로운 항목을 포함하여 감사 테이블에 기록 때문에) 아무것도 변경되지

당신이 Appraoch 1 가면 항목에 대해 존재하지 않는 경우

  • 범위가 넓어지면 모든 삽입 행이 제거 된 행과 새로운 삽입 행을 구분하는 것이 어렵습니다 (삭제 날짜 기억이 필요함).

  • +0

    이 질문/게시물에 대한 모든 생각을 적어서 다시 읽은 후에도 동일한 생각을 가지고있었습니다. 접근법 2는 더 나은 것으로 보인다. 작은 머리 너머는 무시해도됩니다. 귀하의 의견을 보내 주셔서 감사합니다. –

    0

    우리가 많이 사용하는 세 번째 방법은 관심있는 열만 감사하고 각 행에 'new'와 'old'값을 모두 저장하는 것입니다.

    "이름"열이있는 경우 감사 테이블에는 "name_old"및 "name_new"가 있습니다.

    INSERT 트리거에서 "name_old"는 기본 설정에 따라 공백/null로 설정되고 "name_new"는 INSERTED에서 설정됩니다. UPDATE 트리거에서 "name_old"는 DELETED에서 설정되고 "name_new"는 INSERTED에서 설정됩니다. DELETE 트리거에서 "name_old"는 DELETED에서 "new_name"은 blank/null로 설정됩니다.

    (또는 당신은 FULL 조인을 사용하는 모든 경우에 하나의 트리거) VARCHAR 필드에 대한

    , 이것은 좋은 생각처럼 보이지 않을 수도 있지만, INTEGER, DATETIME 등을 위해 그것은 매우 있다는 장점을 제공한다 업데이트의 차이를 쉽게 알 수 있습니다.

    e.e. 당신이 당신의 실제 테이블의 수량 필드를 가지고 7 5를 업데이트 할 경우, 당신은 감사 테이블에있는 것 :

    quantity_old quantity_new 
          5    7 
    

    쉽게 당신이 양이 특정 시간에이 증가 된 것을 계산할 수 있습니다.

    감사 테이블에 별도의 행이있는 경우 차이점을 계산하기 위해 "다음"행과 조인해야합니다. 어떤 경우에는 까다로울 수 있습니다 ...

    +0

    응답 해 주셔서 감사합니다. 나는이 접근 방법을 이전에 들어 보았지만 결코 구현하지 않았다. 나는 그것에 대해 더 생각할 것이다. 감사합니다, _UB –

    관련 문제