2013-08-13 3 views
1

내 데이터베이스를 재 검증하는 방법은 다음과 같은 구조가 : 당신이 볼 수 있듯이PostgreSQL의 : 검사에게

CREATE TYPE instrument_type AS ENUM (
    'Stock', 
... 
    'Currency', 
... 
); 

CREATE FUNCTION get_instrument_type(instrument_id bigint) RETURNS instrument_type 
    LANGUAGE plpgsql STABLE RETURNS NULL ON NULL INPUT 
AS $$ 
    BEGIN 
     RETURN (SELECT instr_type FROM instruments WHERE id = instrument_id); 
    END 
$$; 

CREATE TABLE instruments (
    id bigserial PRIMARY KEY, 
    instr_type instrument_type NOT NULL, 
... 
); 

CREATE TABLE countries_currencies (
... 
    curr bigint NOT NULL 
     REFERENCES instruments (id) 
      ON UPDATE CASCADE ON DELETE CASCADE 
     CHECK (get_instrument_type(curr) = 'Currency'), 
... 
); 

, 나는 악기를위한 하나 개의 공통 테이블을 사용합니다. 해당 테이블을 참조하는 많은 외래 키가 있습니다. 하지만 countries_currencies와 같은 일부 테이블에서는 참조 된 항목이 '통화'이어야합니다. 이후 CHECK 제약 조건에서 하위 쿼리를 사용할 수 없기 때문에 함수를 사용해야합니다. 어느 날 나쁜 사람이 instrument_type을 'Currency'에서 다른 것으로 변경하게 될 수도 있습니다. 수정 된 계좌를 참조하는 countries_currencies 테이블에 행이있는 경우 CHECK는이 행에 대해 유효하지 않게됩니다. 그러나 CHECK는 새 행에 적용되며 기존 행에는 적용되지 않습니다.

CHECK를 재확인하는 표준 방법이 있습니까? 일반 데이터 무결성 검사의 일부로 이러한 절차를 실행하고 싶습니다.

P. 나는 테이블 악기에 방아쇠를 쓰고 무엇인가가 망가질 수 있다면 변화를 막을 수 있다고 생각합니다. 그러나 참조하는 모든 테이블과 제약 조건을 확인해야하므로 오류가 발생하기 쉽습니다.

+0

. 테이블 상속의 경우 일 수도 있습니다. 왜냐하면 실제로'통화 '인 특정 악기의 하위 집합을 데이터베이스의 자체 엔티티로 취급하기를 원하기 때문입니다. 또는 "더 단순한"관계형 정규화 용어에서, 아마도 '도구'를 참조하는 중간 '통화'테이블이 필요합니다. – IMSoP

+0

@IMSoP, PostgreSQL의 상속에는 몇 가지 제한 사항이 있습니다. 중요한 것은 상속 된 모든 테이블에 고유 한 인덱스가 없다는 것입니다. –

+0

@IMSoP, 나는 다른 접근 방식을 시도하지만 각각 고유 한 제한이 있습니다. Itermediary 테이블 접근법에서는 instr_type = 'currency'인 각 행이 중간 테이블에서 비슷한 행을 가져야합니다. 따라서 각 통화를 중개자로 복사하려면 트리거가 필요합니다. 또 다른 접근법은 countries_currencies 테이블에 instr_type을 가지고 외부 키에 사용하는 것입니다. 그러나 이것 역시 표준화되지 않았습니다. 어쨌든 답변 주셔서 감사합니다! –

답변

2

당신은 단순히 CHECK를 트리거하는 곳에서 모든 행을 업데이트 할 수있다 : 나는 오히려 절차 적 코드에 의존하지 않고 스키마에 제약을 결합이 대안 방법이 있는지 생각하기 위해 노력하고있어

UPDATE countries_currencies SET curr = curr; 
+0

실제로 작동하는지 궁금해서 간단한 테스트 케이스를 만들었고 실제로 check 함수를 실행합니다. http://www.sqlfiddle.com/#!12/d2bc5/5 – IMSoP

+0

@PinnyM, 감사합니다. . 이것은 놀라 울 정도로 간단합니다. –