2012-06-26 5 views
1

나는 우리가 제공하는 서비스에 대한 "서비스"표를 가지고 있습니다. 녹음을 필요로하는 데이터 중입니다 같은 몇몇 작은 일대 다 관계합니다 (SERVICE_ID에 외래 키 제약 조건을 가진 모든) : 내가 가진 문제는 내가 업데이트의 역사를 유지하려는 것입니다일대 다 관계가있는 테이블에서 레코드 기록을 유지 보수하는 방법은 무엇입니까?

service_owners -- user_ids responsible for delivery of service 
service_tags -- e.g. IT, Records Management, Finance 
customer_categories -- ENUM value 
provider_categories -- ENUM value 
software_used -- self-explanatory 

테이블에 업데이트 트리거를 사용하는 서비스에 대해 원래 열과 일치하는 기록 테이블에 삽입을 수행합니다. 그러나 각각의 일대 다 관계에 대해 별도의 테이블과 외래 키를 사용하여 위의 데이터에 대한 표준화 된 접근 방법을 사용하면 이러한 테이블에 대한 업데이트가 서비스 기록에서 인식되지 않습니다.

누구에게 의견이 있습니까? 서비스 기록의 무결성을 유지하기 위해 서비스 테이블에 하위 키를 저장해야하는 것처럼 보입니다. 구분 된 텍스트 필드는 유효한 접근법인가요? 아니면 postgreSQL을 사용하고 있으므로 배열도 유효한 옵션입니까? 이것들은 다소 더러운 느낌이 든다!

감사합니다.

+0

기록 테이블을 정규화 할 필요가 없습니다. 진정한 역사가 되려면 역사 행이 기록 된 당시 카테고리의 값을 포함해야합니다. –

답변

2

테이블 인 경우 :

create table T (
    ix int identity primary key, 
    val nvarchar(50) 
) 

그리고 당신의 기록 테이블은 다음과 같습니다

create table THistory (
    ix int identity primary key, 
    val nvarchar(50), 
    updateType char(1), -- C=Create, U=Update or D=Delete 
    updateTime datetime, 
    updateUsername sysname 
) 

은 그럼 그냥 관심의 모든 테이블에 업데이트 트리거를 넣을 필요가있다. 그런 다음 해당 시점의 관계가 무엇인지 판별하기 위해 과거/현재 테이블의 상태를 확인할 수 있습니다.

+0

안녕하세요. 이것은 제가 생각한 것입니다 만, start_date 및 end_date 열이있는 삽입 전용 자식 테이블이 필요하지 않습니까? 그러면 하위 테이블의 실행 기록 데이터가 활성 데이터와 함께 저장되기 시작하여 테이블이 팽창합니다.이것은 서비스 테이블 자체의 ENUM 배열 또는 int 배열 열보다 확실히 바람직한가? 감사. – circular

+0

활성 테이블과 히스토리 테이블 만 있으면됩니다. 히스토리 테이블은 관계가 필요하지 않으며, 활성 테이블의 모든 행에 대한 히스토리 사본 만 보유합니다. 활성 테이블은 히스토리 테이블을 전혀 참조하지 않습니다. 활성 테이블이 업데이트 될 때마다 트리거는 히스토리 테이블이 새 데이터로 새 행을 가져 오도록합니다. – Ben

+0

테이블 Thistory의 대부분의 열을 NOT NULL로 설정해야한다고 생각합니다. (유스 케이스에 따라 다르다!) – RoachLord

2

가능한 모든 데이터베이스에서 배열을 사용하지 마십시오.

당신이 여기서 말하는 정확한 이유에 대한 업데이트가 마음에 들지 않습니다 ... 쓰는 동안 정보가 손실됩니다. 내 대답은 아주 간단합니다 ... 업데이트하지 마십시오. 당신이 이것을 구현할 수있는 시점에 있는지 확신 할 수는 없지만, 만약 주 테이블 자체를 사용하여 히스토리를 저장하는 것이 좋습니다 (두 번째 히스토리 테이블 세트 필요 없음).

기본 헤더 테이블에 '활성'이라는 열을 추가하십시오. 문자 또는 비트 (0은 꺼져 있고 1은 켜짐) 일 수 있습니다. 그런 다음 약간의 방아쇠 마술입니다 ... 업데이트가 수행되면 '0'(또는 비활성) 상태로 덮어 쓰여진 레코드와 동일한 테이블에 행을 삽입 한 다음 기존 행을 업데이트합니다 (이 경우 프로세스는 활성 레코드의 ID 열을 동일하게 유지하고 새로 삽입 된 레코드는 새 ID가있는 비활성 테이블입니다).

데이터가 적 (일반적으로 인정 하듯이 ... 꽤 많은 행을 저장하는) 손실되지 않고 역사를 쉽게 선택하여 볼 수있는이 방법은 어디에서 활성 = 0

당신이 경우 여기에 통증은 이미 구현 된 작업 ...이 테이블에 해당하는 기존 쿼리는 모두 활성 열에 대한 검사를 포함하도록 업데이트해야합니다. 새 시스템을 설계하는 경우이 솔루션을 구현하기가 매우 쉽지만 오랜 응용 프로그램 인 경우 고통이 발생합니다. 불행하게도 기존 보고서에는 where 절을 수정할 수있을 때까지 off 및 on 레코드가 모두 포함됩니다.

관련 문제