변경 로그 / 감사 데이터베이스 테이블을위한 최상의 디자인? [닫은]


114

다른 변경 로그 / 감사 (추가, 삭제, 수정 등)를 저장하기 위해 데이터베이스 테이블을 만들어야합니다. 특별히 자세한 정보를 저장할 필요가 없으므로 다음과 같은 내용을 생각하고있었습니다.

  • id (이벤트 용)
  • 트리거 한 사용자
  • 이벤트 이름
  • 이벤트 설명
  • 이벤트의 타임 스탬프

여기에 뭔가 빠졌나요? 복잡하게 만들 계획은 없지만 (이벤트 유형에 대한 다른 테이블을 만드는 것은 내 필요에 따라 문제가되지 않기 때문에) 당연히 디자인을 계속 개선 할 수 있습니다.


나는 당신의 대답을 읽고 아무도 법에 대해 이야기하지 않는다는 것에 놀랐습니다. 나는 일부 법률이나 좋은 관행 문서가 (읽기 전용) 감사 테이블을 어떻게 구현해야하는지 설명한다는 것을 알고 있습니다. 그러나 나는 이것보다 더 많은 정보가 없습니다. 나는 그것이 존재한다는 것을 알고 있습니다. 나는 21 일부 11 CFR에 감사 추적에 대해 생각하고 있어요
Bastien Vandamme

답변:


70

제가 작업중인 프로젝트에서 감사 로그는 설명하신 것과 같이 매우 최소한의 디자인에서 시작되었습니다.

event ID
event date/time
event type
user ID
description

아이디어는 똑 같았습니다. 단순하게 유지하는 것입니다.

그러나이 최소한의 디자인으로는 충분하지 않다는 것이 금방 분명해졌습니다. 일반적인 감사는 다음과 같은 질문으로 요약됩니다.

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

따라서 SQL을 사용하여 이러한 질문에 신속하게 답할 수 있도록 감사 테이블에 두 개의 추가 열이 추가되었습니다.

object type (or table name)
object ID

이때 감사 로그의 디자인이 실제로 안정화되었습니다 (현재 몇 년 동안).

물론 마지막 "개선"은 서로 게이트 키가있는 테이블에서만 작동합니다. 하지만 그거 알아? 감사 할 가치가있는 모든 테이블에는 이러한 키가 있습니다!


이 디자인 ( '설명'기반 감사 추적)에서 내가 가진 유일한 문제는 해당 분야에서 사용되는 언어를 현지화하는 것입니다.
Sam Wilson

@Sam 나는 그런 문제가 보이지 않는다. 만약 메시지가 시스템 생성이라면 여기에서 번역 문자열에 키를 사용한다.
JCM

4
@Hiru : 두 개 이상의 별개의 개념을 하나의 열로 "혼합"하면 조만간 역효과가 발생하는 경우가 더 많습니다. 예를 들어, 이벤트 유형과 객체 유형을 "혼합"하면 "주어진 유형의 모든 객체에 대한 레코드 표시"및 "주어진 유형의 모든 이벤트에 대한 레코드 표시"와 같은 쿼리에 영향을 미칩니다 (쿼리는 더 복잡하고 대부분 훨씬 느리게 작동합니다.)
Yarik

3
이러한 열 외에도 구조화 된 설명 / 구조화 된 이벤트 페이로드를 위한 추가 열이있을 수 있습니다 . 이 열은 컴퓨터에서 읽을 수있는 형식 인 XML / JSON으로 이벤트 세부 정보 (복잡성에 관계없이)를 보유합니다. 직렬화, 쿼리 (적어도 Postgres / MSSQL에서는), 추론하기 쉽습니다.
turdus-merula

1
@Benjamin : 대답은 도메인 모델 (일명 비즈니스 모델)에 있습니다. 모델이 엔티티의 동시 생성을 허용하는 경우 (예 : 논리적 트랜잭션의 일부로) 정확히 동일한 타임 스탬프를 가진 여러 로그 레코드를 갖는 데 문제가 없습니다. 예를 들어 구매 주문 (트랜잭션) 생성에 N 개의 주문 항목 생성이 포함될 수있는 경우 해당하는 모든 1 + N 로그 레코드는 동일한 타임 스탬프를 갖습니다. 이러한 로그의 후속 분석은 이러한 1 + N 레코드를 독립적 인 레코드가 아니라 논리적 트랜잭션의 요소로 취급하여이를 활용할 수 있습니다. 이것이 의미가 있기를 바랍니다.
Yarik

24

또한 감사 세부 정보 테이블에서 감사되는 테이블의 기본 키뿐만 아니라 이전 값과 새 값과 해당 값이 생성 된 열을 기록합니다. 감사 테이블이 필요한 것이 무엇인지 생각하십니까? 누가 언제 변경했는지 알고 싶을뿐만 아니라 잘못된 변경이 발생했을 때 데이터를 복구하는 빠른 방법을 원합니다.

디자인하는 동안 데이터를 복구하는 코드를 작성해야합니다. 회복이 필요한 경우에는 일반적으로 서둘러서 미리 준비하는 것이 가장 좋습니다.


1
사람들이 마지막 게시물을 무시하는 이유를 이해할 수 없습니다.
Maddy.Shik

3
이벤트 소싱 은 기록을 유지하면서 롤백 기능을 제공하는 대체 접근 방식입니다.
Sam

23

테이블 / 열 이름, 업데이트가 이루어진 컴퓨터 / 응용 프로그램 등과 같이 감사 할 수있는 몇 가지 사항이 더 있습니다.

이제 이것은 얼마나 상세한 감사가 실제로 필요한지, 어떤 수준에서 필요한지에 달려 있습니다.

우리는 자체 트리거 기반 감사 솔루션을 구축하기 시작했으며 모든 것을 감사하고 복구 옵션도 마련하고 싶었습니다. 이것은 너무 복잡한 것으로 판명되어 트리거 기반의 타사 도구 인 ApexSQL 감사를 리버스 엔지니어링하게되었습니다. 를 자체 맞춤형 솔루션을 만들었습니다.

팁 :

  • 이전 / 이후 값 포함

  • 기본 키 저장을위한 3-4 개의 열 포함 (복합 키인 경우)

  • 이미 Robert가 제안한대로 기본 데이터베이스 외부에 데이터 저장

  • 특히 복구에 필요할 수있는 보고서를 준비하는 데 상당한 시간을 할애하십시오.

  • 호스트 / 애플리케이션 이름 저장 계획 – 의심스러운 활동을 추적하는 데 매우 유용 할 수 있습니다.


2
구입하는 대신 리버스 엔지니어링을하는 이유는 무엇입니까?
Jowen 2015 년

1
제품을보다 효율적으로 관리
Tebe

1
그들이 당신을 고소하지 않았기를 바랍니다.
Sorter

9

여기와 비슷한 질문에 흥미로운 답변이 많이 있습니다. 개인적인 경험에서 추가 할 수있는 것은 다음과 같습니다.

  1. 감사 테이블을 다른 데이터베이스에 넣으십시오. 이상적으로는 원본 데이터와 분리해야합니다. 데이터베이스를 복원해야하는 경우 감사 추적을 복원하고 싶지는 않습니다.

  2. 가능한 한 많이 비정규 화하십시오. 테이블이 원래 데이터에 대해 가능한 한 적은 종속성을 갖기를 원합니다. 감사 테이블은 데이터를 검색하기 위해 간단하고 매우 빠릅니다. 데이터를 얻기 위해 다른 테이블에 대한 멋진 조인이나 조회가 없습니다.


8
비정규 화 된 데이터는 적절한 인덱스가있는 정규화 된 데이터에 비해 실제로 더 빨리 읽을 수 있습니까? (모든 중복으로 인해 HDD에서 더 많은 데이터를 읽지 않습니까?)
Sam

4

테이블에있는 것 :-

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

일반 ID는 업데이트 된 테이블의 행을 가리키고 테이블 이름은 해당 테이블의 이름 (문자열)입니다. 좋은 DB 디자인은 아니지만 매우 유용합니다. 모든 테이블에는 단일 대리 키 열이 있으므로 잘 작동합니다.


2
"금액"은 무엇을 의미합니까?
turdus-merula

이것은 재정적 인 응용 프로그램이므로 승인되는 것의 달러 가치 등입니다.
WW.

4

일반적으로 사용자 지정 감사 (다양한 테이블 생성)는 잘못된 옵션입니다. 일부 로그 활동을 건너 뛰기 위해 데이터베이스 / 테이블 트리거를 비활성화 할 수 있습니다. 사용자 정의 감사 테이블은 변조 될 수 있습니다. 신청이 중단되는 예외가 발생할 수 있습니다. 강력한 솔루션 설계의 어려움은 말할 것도 없습니다. 지금까지이 토론에서 매우 간단한 사례를 보았습니다. 현재 데이터베이스 및 권한있는 사용자 (DBA, 개발자)와 완전히 분리해야합니다. 모든 주류 RDBMS는 DBA조차도 비밀리에 비활성화하거나 조작 할 수없는 감사 기능을 제공합니다. 따라서 RDBMS 공급 업체에서 제공하는 감사 기능이 첫 번째 옵션이어야합니다. 다른 옵션은 분해 된 정보를 일부 형태의 감사 데이터웨어 하우스 또는 실시간 이벤트 처리기로 끝나는 메시징 시스템으로 푸시하는 타사 트랜잭션 로그 판독기 또는 사용자 지정 로그 판독기입니다. 요약해서 말하자면: Solution Architect / "Hands on Data Architect"는 요구 사항에 따라 그러한 시스템을 지정하는 데 관여해야합니다. 해결책을 위해 개발자에게 넘기는 것은 보통 너무 심각한 일입니다.


3

이를 수행하는 방법에는 여러 가지가 있습니다. 내가 가장 좋아하는 방법은 :

  1. mod_user소스 테이블 (로그하려는 필드)에 필드를 추가합니다 .

  2. 로깅하려는 필드 log_datetime와 및 seq_num필드 가 포함 된 로그 테이블을 만듭니다 . seq_num기본 키입니다.

  3. 모니터링되는 필드가 변경 될 때마다 현재 레코드를 로그 테이블에 삽입하는 트리거를 소스 테이블에 빌드하십시오.

이제 모든 변경 사항에 대한 기록과 누가 변경했는지 확인했습니다.


그래서 ... mod_user 필드는 무엇을해야합니까?
conny

1
누가 변경했는지 알려주십시오. 코드 업데이트에는 해당 필드를 현재 사용자로 설정하는 내용이 포함되어야합니다.
JosephStyons

그러면 삭제는 어떻습니까? 행을 삭제하면 mod_user 열의 값을 어떻게 처리합니까?
Kenn Cal

@KennCal Triggers는 가상 테이블을 사용할 수 있으며 동일한 트리거 내에서 전후의 데이터를 볼 수 있습니다. 수술은 중요하지 않습니다. stackoverflow.com/questions/6282618/...
르낭 카발리 에리에게

2
@KennCal 맞습니다. 삭제 트리거는 해당 정보를 저장해야합니다. 악마는 세부 사항에 있습니다. SQL 인증을 사용하는 경우 트리거는 [select CURRENT_USER]를 실행할 수 있습니다. 클라이언트 응용 프로그램 인 경우 클라이언트 코드에서 누구인지 알려야합니다. API 호출 인 경우 삭제 사용자는 호출에 대한 필수 매개 변수 여야합니다.
JosephStyons

1

분리 원칙에 따라 :

  1. 감사 데이터 테이블은 기본 데이터베이스와 분리되어야합니다. 감사 데이터베이스에는 많은 히스토리 데이터가있을 수 있으므로 메모리 활용 관점에서 별도로 유지하는 것이 좋습니다.

  2. 트리거를 사용하여 전체 데이터베이스를 감사하지 마십시오. 지원해야 할 다른 데이터베이스가 엉망이 될 수 있습니다. DB2, SQLServer, Mysql 등에 대해 작성해야합니다.

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