2014-04-24 2 views
1

는 내가 가진 : Info를 열 personId, laptopIdprice로 : 나는 테이블을 가지고 가정.데이터베이스 : 원자 트리거

탁 : 노트북의 가격 요약이 일정 이상인 경우 Person 테이블에 삽입하지 못하도록하십시오.

나쁜 솔루션 : 트리거를

문제를 추가 그 해결책은 원자 없습니다. triger와 조건을 검사하는 사이에 다른 작업을 INSERT 할 수 있습니다.

질문 :어떻게하면 안심할 수 있습니까? 당신이 Info에 구체화 된 뷰 로그를 만들 가정

+0

적용하려고하는 비즈니스 제약 조건을 따르고 있는지 확실하지 않습니다. 모든 행에 걸쳐'sum (price)'가 어떤 상수를 초과하게되면 누군가가 행을 삽입하는 것을 막고 싶다는 말입니까? –

+0

@JustinCave'sum (price)'는 각각의 다른 사람에게 어떤 상수를 초과해서는 안됩니다. 예를 들어, 직원 Nockolas는 요약 할 때 $ 1355 이상의 비용이 드는 랩톱을 가질 수 없습니다. –

답변

2

, 당신이이 경우에 위반 될 전망을 구체화에

CREATE MATERIALIZED VIEW mv_check_totals 
    REFRESH FAST 
    ON COMMIT 
AS 
SELECT personID, 
     sum(price) total_price 
    FROM info 
GROUP BY personID 
HAVING sum(price) > <<some constant>> 

당신은 다음 제약 조건을 만들 수 커밋에 빠른 새로 고침을 수행 구체화 된 뷰를 만들 수 있습니다 구체화 된 뷰에 모든 행이 표시됩니다.

ALTER TABLE mv_check_totals 
    ADD CONSTRAINT constraint_name 
     CHECK(personID IS NULL) 

이 위치를 사용하면 총 비용이 커미트 시간에 점검됩니다. INSERT만큼 많은 행을 허용 할 수 있습니다 (결국 다른 사람이 이전에 커밋 할 다른 세션의 기존 행을 삭제할 수 있습니다). 그러나 비즈니스 규칙을 위반하는 경우 변경 사항을 커밋하지 않을 것입니다. 이는 지연된 제약 조건에서 얻을 수있는 것과 매우 흡사합니다. 그러나 더 똑똑한 응용 프로그램은 커밋이 실패했다는 것을 인식하고 특정 INSERT에 대한 오류를보고하기보다는 사용자에게 사실을 알리도록 요구합니다.

이 구현에서 비즈니스 규칙이 충족되면 구체화 된보기가 비어 있도록 상수를 구체화 된보기 정의에 놓습니다. 따라서 총 저장 비용을 피할 수 있습니다. 그러나 HAVING 절을 생략하고 제약 조건에 상수를 넣을 수 있습니다. 즉, 추가 데이터를 저장하고 있음을 의미합니다. 그러나 그것은 앞으로의 상수 변경을 더 쉽게 만듭니다. 그리고 보고서에 발표 할 내용이 있다면 각 사람마다 total_price을 구체화합니다.

관련 문제