CREATE RULE
CREATE RULE
새 재작성 규칙(rewrite rule)을 정의하는 명령이에요. 테이블이나 뷰에 대해 특정 이벤트가 일어날 때 다른 동작을 실행하도록 바꿔주는 규칙입니다.
출처: PostgreSQL 문서
본문
문법 (Synopsis)
CREATE [ OR REPLACE ] RULE name AS ON event
TO table_name [ WHERE condition ]
DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }
where event can be one of:
SELECT | INSERT | UPDATE | DELETE
설명 (Description)
CREATE RULE는 지정한 테이블이나 뷰에 적용되는 새 규칙을 정의해요. CREATE OR REPLACE RULE는 새 규칙을 만들거나, 같은 테이블의 같은 이름의 기존 규칙을 교체합니다.
PostgreSQL 규칙 시스템을 이용하면 데이터베이스 테이블의 삽입, 갱신, 삭제에 대해 대체 동작을 정의할 수 있어요. 대략적으로 말해, 규칙은 특정 테이블에서 특정 명령이 실행될 때 추가 명령이 실행되도록 만듭니다. 또는 INSTEAD 규칙이 특정 명령을 다른 명령으로 대체하거나, 명령이 전혀 실행되지 않게 할 수 있어요. 규칙은 SQL 뷰를 구현하는 데도 쓰입니다. 규칙은 사실상 명령 변환 메커니즘, 즉 명령 매크로라는 점을 이해하는 게 중요해요. 변환은 명령 실행이 시작되기 전에 일어납니다. 물리적인 각 행마다 독립적으로 발화되는 연산을 원한다면 규칙이 아니라 트리거를 써야 할 거예요. 규칙 시스템에 대한 더 자세한 정보는 39장에 있습니다.
현재 ON SELECT 규칙은 뷰에만 붙일 수 있어요. 그런 규칙은 "_RETURN"이라는 이름이어야 하고, 무조건적(조건 없는) INSTEAD 규칙이어야 하며, 단일 SELECT 명령으로 이루어진 동작을 가져야 합니다. 이 명령이 뷰의 보이는 내용을 정의해요. (뷰 자체는 기본적으로 저장 공간이 없는 더미 테이블입니다.) 그런 규칙은 구현 세부 사항으로 보는 게 좋아요. 뷰는 CREATE OR REPLACE RULE "_RETURN" AS ...로도 재정의할 수 있지만, CREATE OR REPLACE VIEW를 쓰는 편이 더 나은 스타일입니다.
ON INSERT, ON UPDATE, ON DELETE 규칙(또는 목적에 충분한 그 하위 집합)을 정의해 뷰의 갱신 동작을 다른 테이블에 대한 적절한 갱신으로 대체하면, 갱신 가능한 뷰(updatable view) 같은 착각을 만들어낼 수 있어요. INSERT RETURNING 등을 지원하려면 각 규칙에 적절한 RETURNING 절을 꼭 넣어야 합니다.
복잡한 뷰 갱신에 조건부 규칙을 쓰려고 하면 한 가지 제약이 있어요. 뷰에서 허용하려는 각 동작마다 무조건적 INSTEAD 규칙이 하나 있어야 합니다. 규칙이 조건부이거나 INSTEAD가 아니면, 시스템은 여전히 그 갱신 동작을 거부하는데, 어떤 경우에는 뷰의 더미 테이블에서 그 동작을 수행하게 될 수도 있다고 생각하기 때문이에요. 조건부 규칙으로 유용한 모든 경우를 다루려면, 시스템이 더미 테이블을 갱신하라고 요청받는 일이 없을 거라고 이해하도록 무조건적 DO INSTEAD NOTHING 규칙을 추가하세요. 그런 다음 조건부 규칙을 비-INSTEAD로 만들면, 적용되는 경우 기본 INSTEAD NOTHING 동작에 덧붙여져요. (하지만 이 방법은 현재 RETURNING 쿼리를 지원하지는 않습니다.)
참고
자동으로 갱신 가능할 만큼 단순한 뷰(see CREATE VIEW)는 갱신 가능해지는 데 사용자 정의 규칙이 필요하지 않아요. 그래도 명시적 규칙을 만들 수는 있지만, 자동 갱신 변환이 보통 명시적 규칙보다 성능이 좋습니다.
규칙 대신 INSTEAD OF 트리거(see CREATE TRIGGER)를 쓰는 것도 고려해 볼 만한 대안이에요.
파라미터 (Parameters)
name— 만들 규칙의 이름. 같은 테이블의 다른 규칙 이름과 달라야 해요. 같은 테이블과 같은 이벤트 유형의 여러 규칙은 이름 알파벳 순으로 적용됩니다.event—SELECT,INSERT,UPDATE,DELETE중 하나.ON CONFLICT절을 포함한INSERT는INSERT또는UPDATE규칙이 있는 테이블에서는 쓸 수 없어요. 갱신 가능한 뷰를 쓰는 것을 고려해 보세요.table_name— 규칙이 적용되는 테이블 또는 뷰의 이름(스키마 한정 가능).condition—boolean을 반환하는 SQL 조건식. 이 조건식은NEW와OLD외에는 어떤 테이블도 참조할 수 없고, 집계 함수를 포함할 수 없습니다.INSTEAD— 명령이 원래 명령 대신 실행돼야 함을 나타냄.ALSO— 명령이 원래 명령에 더해 실행돼야 함을 나타냄.ALSO도INSTEAD도 지정하지 않으면ALSO가 기본이에요.command— 규칙 동작을 이루는 명령(들). 유효한 명령은SELECT,INSERT,UPDATE,DELETE,NOTIFY입니다.
condition과 command 안에서는 특수 테이블 이름 NEW와 OLD로 참조 테이블의 값을 가리킬 수 있어요. NEW는 ON INSERT와 ON UPDATE 규칙에서 삽입되거나 갱신되는 새 행을 가리키는 데 유효하고, OLD는 ON UPDATE와 ON DELETE 규칙에서 갱신되거나 삭제되는 기존 행을 가리키는 데 유효합니다.
주의 사항 (Notes)
테이블에 대한 규칙을 만들거나 바꾸려면 그 테이블의 소유자여야 해요.
뷰에 대한 INSERT, UPDATE, DELETE 규칙에서는 뷰의 컬럼을 방출하는 RETURNING 절을 추가할 수 있어요. 이 절은 규칙이 각각 INSERT RETURNING, UPDATE RETURNING, DELETE RETURNING 명령에 의해 발화됐을 때 출력을 계산하는 데 사용됩니다. RETURNING 없는 명령으로 규칙이 발화되면 규칙의 RETURNING 절은 무시돼요. 현재 구현은 무조건적 INSTEAD 규칙만 RETURNING을 포함할 수 있게 하며, 같은 이벤트의 모든 규칙 중 RETURNING 절은 최대 하나만 있을 수 있어요. (이렇게 해서 결과 계산에 쓰일 RETURNING 절 후보가 하나만 존재하게 보장합니다.) 사용 가능한 규칙에 RETURNING 절이 없으면 뷰에 대한 RETURNING 쿼리는 거부됩니다.
순환 규칙을 피하는 데 매우 주의해야 해요. 예를 들어 다음 두 규칙 정의는 각각 PostgreSQL이 받아들이지만, SELECT 명령은 규칙의 재귀적 확장 때문에 PostgreSQL이 오류를 보고하게 됩니다:
CREATE RULE "_RETURN" AS
ON SELECT TO t1
DO INSTEAD
SELECT * FROM t2;
CREATE RULE "_RETURN" AS
ON SELECT TO t2
DO INSTEAD
SELECT * FROM t1;
SELECT * FROM t1;
현재 규칙 동작이 NOTIFY 명령을 포함하면, 그 NOTIFY 명령은 무조건 실행돼요. 즉, 규칙이 적용될 행이 하나도 없어도 NOTIFY가 발행됩니다. 예를 들어:
CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable;
UPDATE mytable SET name = 'foo' WHERE id = 42;
조건 id = 42에 맞는 행이 있든 없든, UPDATE 동안 NOTIFY 이벤트 하나가 보내집니다. 이는 향후 릴리스에서 고쳐질 수도 있는 구현 제약이에요.
호환성 (Compatibility)
CREATE RULE는 전체 쿼리 재작성 시스템과 마찬가지로 PostgreSQL 언어 확장이에요.
함께 보기 (See Also)
ALTER RULE, DROP RULE
더 알아보기 (Learn more)
CREATE TRIGGER: 규칙 대신 특정 이벤트마다 독립적으로 발화하는 트리거를 정의하는 명령.ALTER RULE: 기존 규칙을 수정하는 명령.