내가 작업중 인 프로젝트 에서 데이터베이스의 일부 테이블에있는 행의 모든 변경 사항 은 추가 감사 또는 롤백을 위해 추적되어야합니다 . 누가 IP 주소와 시간에서 행을 수정했는지 쉽게 찾고 이전 버전을 복원 할 수 있어야합니다.
비슷한 것은 예를 들어 Stack Exchange에서 사용됩니다. 다른 사람의 질문을 변경하면 내가 변경 한 것을 발견하고 변경 사항을 롤백 할 수 있습니다.
현재 스키마에 평균 비즈니스 앱과 거의 동일한 속성 (아래)이 있다고 가정 할 때 데이터베이스의 객체에 대한 모든 변경 사항을 저장하는 데 사용되는 일반적인 기술은 무엇입니까 ?
- 몇 가지가있을 수 있습니다 : 개체는 상대적으로 작은 크기를 가지고
nvarchar(1000)
예를 들어,하지만 이진 데이터의 거대한 모양은,이 직접, 직접 디스크에 저장하고, 액세스하지 하지 마이크로 소프트 SQL을 통해filestream
, - 데이터베이스로드는 매우 낮으며 전체 데이터베이스는 서버에서 하나의 가상 머신으로 처리됩니다.
- 이전 버전에 대한 액세스는 최신 버전에 대한 액세스만큼 빠를 필요는 없지만 여전히 최신 ¹이어야하고 너무 느리지 않아야합니다 ².
<tl-dr>
나는 다음과 같은 경우에 대해 생각했지만 그러한 시나리오에 대한 실제 경험이 없으므로 다른 사람들의 의견을들을 것입니다.
ID와 버전으로 행을 구별하여 모든 것을 동일한 테이블에 저장하십시오. IMO는 매우 어리 석고 조만간 성능 수준이 떨어질 것입니다. 이 방법을 사용하면 최신 항목 및 버전 추적에 다른 보안 수준을 설정할 수도 없습니다. 마지막으로 모든 쿼리는 작성하기가 더 복잡합니다. 실제로 최신 데이터에 액세스하려면 ID로 모든 것을 그룹화하고 각 그룹에서 마지막 버전을 검색해야합니다.
한 테이블에 최신 버전을 저장하고, 변경 될 때마다 더 이상 사용되지 않는 버전을 다른 스키마의 다른 테이블로 복사하십시오. 결함은 매번 변화하지 않더라도 모든 가치를 저장한다는 것입니다. 변경되지 않은 값을
null
로 설정 하는 것은 해결책이 아닙니다. 값이 언제null
또는로 변경되는지 추적해야하기 때문 입니다null
.한 테이블에 최신 버전을 저장하고 변경된 값 목록을 이전 값과 함께 다른 테이블에 저장하십시오. 두 가지 결함이있는 것 같습니다. 가장 중요한 방법은 동일한 열에서 이기종 유형의 이전 값을 정렬하는 유일한 방법은을 갖는 것
binary(max)
입니다. 두 번째는 이전 버전을 사용자에게 표시 할 때 그러한 구조를 사용하는 것이 더 어렵다는 것입니다.이전 두 지점에서와 동일한 작업을 수행하지만 버전을 별도의 데이터베이스에 저장하십시오. 성능 측면에서 볼 때 동일한 데이터베이스에 이전 버전이 있으면 최신 버전에 대한 액세스 속도가 저하되는 것을 피할 수 있습니다. 여전히, 나는 그것이 조기 최적화이며 동일한 데이터베이스에 이전 및 최신 버전이 병목 현상이 있다는 증거가있는 경우에만 수행해야한다고 생각합니다.
</ tl-dr>
¹ 예를 들어, HTTP 로그에 대해 수행 된대로 변경 사항을 로그 파일에 저장하고 서버로드가 가장 적은 밤에 로그에서 데이터베이스로 데이터를 플러시 할 수 없습니다. 다른 버전에 대한 정보는 즉시 또는 거의 즉시 사용 가능해야합니다. 몇 초 지연이 허용됩니다.
²이 정보는 특정 사용자 그룹에 의해서만 자주 액세스되지는 않지만 버전 목록이 표시 될 때까지 30 초 동안 기다리도록 허용 할 수 없습니다. 다시, 몇 초 지연이 허용됩니다.