이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은에 대해 같은 페이지를 보려고 할 수 있습니다스포츠 토토 결과3_스포츠 토토 결과SL1검은 색버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

38.2. 보기 및 규칙 시스템

views inpostgresqlare 규칙 시스템을 사용하여 구현되었습니다. 실제로, 본질적으로 아니오가 있습니다 차이 :

mytab에서 myview를 선택하십시오 * mytab;

두 명령과 비교 :

테이블 작성 myview (mytab과 같은 열 목록);
myview to myview 대신 규칙 "_return"을 작성하십시오.
    * mytab에서 * 선택;

이것이 바로이기 때문에생성 보다명령은 내부적으로 수행됩니다. 이것은 몇 가지 부작용이 있습니다. 하나 그들 중의 견해에 대한 정보는입니다.PostgreSQL시스템 카탈로그는 정확히 동일합니다 테이블과 마찬가지로. 따라서 파서에게는 절대적으로 아니오가 있습니다 테이블과스포츠 토토 사이트의 차이. 그들은 같은 것입니다 : 처지.

38.2.1. 어떻게select규칙 작업

규칙ON SELECT모두에게 적용됩니다 주어진 명령이 a이더라도 마지막 단계로 쿼리삽입, 업데이트또는삭제. 그리고 그들은 다른 의미를 가지고 있습니다 쿼리를 수정한다는 점에서 다른 명령 유형의 규칙에서 새로운 것을 만드는 대신 제자리에 나무를 제자리에 두십시오. 그래서select규칙이 먼저 설명됩니다.

현재,에는 한 가지 행동 만있을 수 있습니다on Select규칙, 무조건적이어야합니다select행동대신. 이 제한은 규칙을 만드는 데 필요했습니다 일반 사용자를 위해 열 수있을 정도로 안전하고 제한됩니다on Select견해처럼 행동하는 규칙.

이 장의 예제는 일부를 수행하는 두 가지 조인 뷰입니다. 계산 및 더 많은 견해를 차례로 사용합니다. 둘 중 하나 첫 번째보기는에 대한 규칙을 추가하여 나중에 사용자 정의됩니다.삽입, 업데이트삭제최종 결과를 얻을 수 있도록 작동 마법이있는 실제 테이블처럼 행동하는 견해가 될 것입니다. 기능. 이것은 시작하기에 간단한 예제가 아니며 이것은 일을 어렵게 만듭니다. 그러나 하나를 갖는 것이 낫습니다 오히려 단계별로 논의 된 모든 점을 다루는 예 염두에두고 섞일 수있는 많은 다른 것들을 갖는 것보다.

예를 들어, 우리는 약간 필요합니다Min2 정수 값의 하단을 반환하는 함수. 우리는 그것을 만듭니다 처럼:

함수 Min (정수, 정수) 생성 정수를 $$로 반환합니다
    $ 1 <$ 2 그런 다음 $ 1 one $ 2 종료 인 경우 사례를 선택하십시오.
$$ Language SQL Strict;

처음 두 규칙 시스템에서 필요한 실제 테이블 설명은 다음과 같습니다.

테이블 SHOE_DATA 만들기 (
    Shoename 텍스트 - 기본 키
    SH_AVAIL INTEGER - 사용 가능한 쌍
    Slcolor Text - 선호하는 떼 색상
    Slminlen Real, - 최소 신발 끈 길이
    Slmaxlen Real, - 최대 떼 길이
    슬루 니트 텍스트 - 길이 단위
);

테이블 생성 shoelace_data (
    SL_NAME 텍스트 - 기본 키
    SL_AVAIL INTEGER - 사용 가능한 수의 쌍
    SL_COLOR 텍스트 - 신발색
    SL_LEN Real, - 신발성 길이
    SL_UNIT 텍스트 - 길이 단위
);

테이블 장치 생성 (
    UN_NAME 텍스트 - 기본 키
    UN_FACT Real- CM으로 변환하는 요소
);

보시다시피, 신발 매장 데이터를 나타냅니다.

보기는 다음과 같이 생성됩니다.

보기 신발을 만듭니다
    sh.shoename 선택,
           sh.sh_avail,
           Sh.slcolor,
           Sh.slminlen,
           sh.slminlen * un.un_fact as slminlen_cm,
           sh.slmaxlen,
           sh.slmaxlen * slmaxlen_cm as as slmaxlen * un.un_fact,
           Sh.slunit
      Shoe_data Sh, Un
     여기서 sh.slunit = un.un_name;

Shoelace보기를 만듭니다
    s.sl_name 선택,
           s.sl_avail,
           s.sl_color,
           s.sl_len,
           s.sl_unit,
           s.sl_len * u.un_fact as sl_len_cm
      shoelace_data s, unit u
     여기서 s.sl_unit = u.un_name;

Shoe_ready를 View를 만듭니다
    rsh.shoename 선택,
           rsh.sh_avail,
           rsl.sl_name,
           rsl.sl_avail,
           Min (rsh.sh_avail, rsl.sl_avail)은 Total_avail입니다
      Shoe Rsh, Shoelace RSL에서
     여기서 rsl.sl_color = rsh.slcolor
       및 rsl.sl_len_cm = rsh.slminlen_cm
       및 rsl.sl_len_cm <= rsh.slmaxlen_cm;

the스포츠 토토 사이트 만들기명령Shoelace스포츠 토토 사이트 (가장 간단한 것입니다 우리는) 관계를 만들 것입니다Shoelace및 입력pg_rewrite다시 작성 해야하는 재 작성 규칙이 있습니다. 관계Shoelacea 쿼리의 범위 테이블. 규칙에는 규칙 자격이 없습니다 (논의 나중에 비select이후 규칙select현재 규칙을 가질 수 없습니다) 그리고 그것은대신. 그 규칙에 유의하십시오 자격은 쿼리 자격과 동일하지 않습니다. 행동 우리의 규칙에는 쿼리 자격이 있습니다. 규칙의 행동은입니다 사본 인 쿼리 트리 하나selectView Creation Command의 명령문.

참고 :두 개의 추가 범위 테이블 항목NEWandold참조pg_rewrite입장은 아닙니다 에 대한 관심select규칙.

이제 우리는 포기Unit, Shoe_dataandShoelace_data스포츠 토토 사이트에서 간단한 쿼리를 실행합니다.

단위 값에 삽입 ( 'cm', 1.0);
단위 값에 삽입 ( 'm', 100.0);
단위 값에 삽입 ( '인치', 2.54);

Shoe_Data 값 ( 'SH1', 2, 'Black', 70.0, 90.0, 'cm')에 삽입;
Shoe_data 값에 삽입 ( 'sh2', 0, 'black', 30.0, 40.0, 'inch');
Shoe_data 값에 삽입 ( 'sh3', 4, 'brown', 50.0, 65.0, 'cm');
Shoe_data 값에 삽입 ( 'sh4', 3, 'brown', 40.0, 50.0, 'inch');

shoelace_data 값에 삽입 ( 'sl1', 5, 'black', 80.0, 'cm');
shoelace_data 값에 삽입 ( 'sl2', 6, 'black', 100.0, 'cm');
shoelace_data 값에 삽입 ( 'sl3', 0, 'black', 35.0, 'inch');
shoelace_data 값에 삽입 ( 'sl4', 8, 'black', 40.0, 'inch');
shoelace_data 값 ( 'sl5', 4, 'brown', 1.0, 'm')에 삽입;
shoelace_data 값 ( 'sl6', 0, 'brown', 0.9, 'm')에 삽입;
shoelace_data 값에 삽입 ( 'sl7', 7, 'brown', 60, 'cm');
shoelace_data 값에 삽입 ( 'sl8', 1, 'brown', 40, 'inch');

Shoelace에서 *를 선택하십시오.

 sl_name | SL_AVAIL | SL_COLOR | SL_LEN | SL_UNIT | SL_LEN_CM
-----------+----------+----------+-------+-------------------------------------------------------------
 SL1 |        5 | 검은 색 |     80 | cm |        80
 SL2 |        6 | 검은 색 |    100 | cm |       100
 SL7 |        7 | 브라운 |     60 | cm |        60
 SL3 |        0 | 검은 색 |     35 | 인치 |      88.9
 SL4 |        8 | 검은 색 |     40 | 인치 |     101.6
 SL8 |        1 | 브라운 |     40 | 인치 |     101.6
 SL5 |        4 | 브라운 |      1 | m |       100
 SL6 |        0 | 브라운 |    0.9 | m |        90
(8 줄)

이것은 가장 간단합니다select할 수 있습니다 우리의 견해에 따라, 우리는이 기회를 통해 기본 사항을 설명합니다. 규칙보기. 그만큼SELECT * From Shoelace파서에 의해 해석되고 쿼리 트리를 생성했습니다 :

shoelace.sl_name, shoelace.sl_avail 선택을 선택하십시오.
       shoelace.sl_color, shoelace.sl_len,
       shoelace.sl_unit, shoelace.sl_len_cm
  Shoelace Shoelace에서;

그리고 이것은 규칙 시스템에 제공됩니다. 규칙 시스템이 걷는다 범위 테이블을 통해 및 규칙이 있는지 확인합니다. 관계. 범위 테이블 항목을 처리 할 때Shoelace(지금까지 유일한 사람)는를 찾습니다._return쿼리 트리를 사용한 규칙 :

S.SL_NAME, S.SL_AVAIL, SELECT SELECT
       s.sl_color, s.sl_len, s.sl_unit,
       s.sl_len * u.un_fact as sl_len_cm
  Shoelace Old, Shoelace New,
       shoelace_data s, 단위 u
 여기서 s.sl_unit = u.un_name;

보기를 확장하려면 다시 작성자는 단순히 하위 쿼리를 만듭니다. 규칙의 조치 쿼리 트리를 포함하는 범위 테이블 항목 및 이 범위 테이블 항목을 원래 테이블 항목으로 대체합니다. 견해를 참조했습니다. 결과적으로 다시 작성된 쿼리 트리는 거의입니다 입력 한 것과 마찬가지로 :

shoelace.sl_name, shoelace.sl_avail 선택을 선택하십시오.
       shoelace.sl_color, shoelace.sl_len,
       shoelace.sl_unit, shoelace.sl_len_cm
  From (select s.sl_name,
               s.sl_avail,
               s.sl_color,
               s.sl_len,
               s.sl_unit,
               s.sl_len * u.un_fact as sl_len_cm
          shoelace_data s, unit u
         여기서 s.sl_unit = u.un_name) shoelace;

그러나 한 가지 차이점이 있습니다. 하위 쿼리의 범위 테이블에는 두 개의 추가 항목Shoelace oldandShoelace New. 이 항목은 그렇지 않습니다 참조되지 않으므로 쿼리에 직접 참여 하위 쿼리의 조인 트리 또는 대상 목록. 다시 작성자는 그것들을 사용합니다 원래의 액세스 권한 확인 정보를 저장하십시오 보기를 참조하는 범위 테이블 항목에 존재합니다. 이것에서 방법, 집행 인은 여전히 ​​사용자가 적절하다고 확인합니다. 직접 사용하지 않더라도보기에 액세스 할 수있는 특권 다시 작성한 쿼리의보기

그것은 첫 번째 규칙이 적용되었습니다. 규칙 시스템은 계속됩니다 상단 쿼리에서 나머지 범위 테이블 항목을 확인하십시오 ( 이 예제는 더 이상 없으며), 그것은 재귀 적으로 확인합니다. 추가 하위 쿼리의 레인지 테이블 항목을 위해 참조보기. (그러나 그것은 확장되지 않을 것입니다old또는NEW- 그렇지 않으면 우리는 무한합니다 재귀!)이 예에서는에 대한 재 작성 규칙이 없습니다.Shoelace_data또는Unit, 재 작성이 완료되고 위는 플래너에게 제공 된 최종 결과.

이제 우리는 어떤 신발을 찾는 쿼리를 쓰고 싶습니다 현재 상점에 우리는 일치하는 신발 끈을 가지고 있습니다 (색상 및 길이) 및 정확히 일치하는 쌍의 총 수가 더 크거나 동일합니다.

SELECT * FROM SHOE_READY where total_avail = 2;

 떼 이름 | sh_avail | sl_name | SL_AVAIL | Total_avail
----------+----------+---------+-------------------
 sh1 |        2 | SL1 |        5 |           2
 sh3 |        4 | SL7 |        7 |           4
(2 줄)

파서의 출력은 이번에는 쿼리 트리입니다 :

shoe_ready.shoename, shoe_ready.sh_avail,
       shoe_ready.sl_name, shoe_ready.sl_avail,
       Shoe_ready.total_avail
  Shoe_ready Shoe_ready에서
 여기서 shoe_ready.total_avail = 2;

첫 번째 규칙은에 대한 첫 번째 규칙입니다.Shoe_ready스포츠 토토 사이트를보고 쿼리가 발생합니다 나무:

SHOE_READY.SHOENAME, SHOE_READY.SH_AVAIL,
       shoe_ready.sl_name, shoe_ready.sl_avail,
       Shoe_ready.total_avail
  From (select rsh.shoename,
               rsh.sh_avail,
               rsl.sl_name,
               rsl.sl_avail,
               Min (rsh.sh_avail, rsl.sl_avail)은 Total_avail입니다
          Shoe Rsh, Shoelace RSL에서
         여기서 rsl.sl_color = rsh.slcolor
           및 rsl.sl_len_cm = rsh.slminlen_cm
           및 rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
 여기서 shoe_ready.total_avail = 2;

마찬가지로에 대한 규칙신발andShoelace는 범위로 대체됩니다 하위 쿼리 테이블, 3 단계 최종 쿼리로 이어지는 나무:

SHOE_READY.SHOENAME, SHOE_READY.SH_AVAIL,
       shoe_ready.sl_name, shoe_ready.sl_avail,
       Shoe_ready.total_avail
  From (select rsh.shoename,
               rsh.sh_avail,
               rsl.sl_name,
               rsl.sl_avail,
               Min (rsh.sh_avail, rsl.sl_avail)은 Total_avail입니다
          에서 (select sh.shoename,
                       sh.sh_avail,
                       Sh.slcolor,
                       Sh.slminlen,
                       sh.slminlen * un.un_fact as slminlen_cm,
                       sh.slmaxlen,
                       sh.slmaxlen * slmaxlen_cm as as slmaxlen * un.un_fact,
                       Sh.slunit
                  Shoe_data Sh, Un
                 여기서 sh.slunit = un.un_name) rsh,
               (S.SL_NAME 선택,
                       s.sl_avail,
                       s.sl_color,
                       s.sl_len,
                       s.sl_unit,
                       s.sl_len * u.un_fact as sl_len_cm
                  shoelace_data s, unit u
                 여기서 s.sl_unit = u.un_name) rsl
         여기서 rsl.sl_color = rsh.slcolor
           및 rsl.sl_len_cm = rsh.slminlen_cm
           및 rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
 여기서 shoe_ready.total_avail 2;

플래너 가이 나무를 2 레벨 쿼리 트리 : 병적select명령은입니다."당겨졌습니다 위로"중간으로select그 이후 별도로 처리 할 필요가 없습니다. 하지만 중간select상단과는 별개로 유지됩니다. 총 기능이 포함되어 있기 때문입니다. 우리가 그것들을 끌어 당겼다면 최상위의 동작을 바꿀 것입니다select, 우리가 원하지 않는. 그러나 붕괴 쿼리 트리는 다시 쓰기 시스템에없는 최적화입니다. 그 자체로.

38.2.2. 보다 비의 규칙select진술

쿼리 트리의 두 세부 사항은 설명에 닿지 않습니다. 위의보기 규칙. 이것이 명령 유형과 결과입니다 관계. 실제로보기 규칙에 따라 명령 유형이 필요하지 않습니다. 그러나 결과 관계는 쿼리의 방식에 영향을 줄 수 있습니다. Rewriter는 특별한주의를 기울여야하기 때문에 결과 관계는보기입니다.

쿼리 트리 간에는 몇 가지 차이점이 있습니다select그리고 다른 명령을위한 것입니다. 분명히, 그들은 다른 명령 유형을 가지고 있으며 명령을 A 이외select, 결과 관계 결과가 진행되는 범위 테이블 항목을 가리 킵니다. 다른 모든 것은 절대적으로 동일합니다. 그래서 두 개의 테이블을 가지고T1andT2aandB, 두 가지 진술에 대한 쿼리 트리 :

t1, t2에서 t2.b를 선택하십시오. 여기서 t1.a = t2.a;

T1 Set T2에서 T1 세트 B = T2.B를 업데이트합니다. 여기서 t1.a = t2.a;

거의 동일합니다. 특히:

  • 범위 테이블에는 테이블의 항목이 포함되어 있습니다T1andT2.

  • 대상 목록에는 열을 가리키는 하나의 변수가 포함되어 있습니다B테이블의 범위 테이블 항목T2.

  • 자격 표현식은 열을 비교합니다a평등을위한 레인지 테이블 항목의 두 항목.

  • 가입 트리는 간단한 결합을 보여줍니다T1andT2.

결과는 두 쿼리 트리가 비슷한 결과를 초래한다는 것입니다. 실행 계획 : 둘 다 두 테이블에 합류합니다.업데이트누락 된 열에서T1플래너가 대상 목록에 추가됩니다. 최종 쿼리 트리는 다음과 같이 읽습니다.

업데이트 t1은 t2에서 t1.a = t2.a;에서 a = t1.a, b = t2.b를 설정합니다.

따라서 Executor는 Join을 통해 달리면 정확히 생성됩니다. 동일한 결과 세트 :

t1.a, t2.b에서 t1.a = t2.a;를 선택하십시오.

그러나 약간의 문제가 있습니다업데이트: 가입은 조인의 결과가 무엇을 의미하는지 신경 쓰지 않습니다. 그것 결과 집합을 생성합니다. 하나라는 사실select명령이고 다른 하나는입니다.업데이트집행자, 이것이라는 것을 알고있는 곳업데이트, 그리고이 결과가 들어가야한다는 것을 알고 있습니다. 테이블T1. 그러나 어떤 행이든 새 행으로 대체해야합니까?

이 문제를 해결하려면 다른 항목이 대상에 추가됩니다. 목록업데이트(및 in삭제) 문 : 현재 튜플 ID (CTID). 이것은 시스템 열입니다 파일 블록 번호와 블록에 위치를 포함하는 열. 테이블을 알고,CTID원래 행을 검색하는 데 사용될 수 있습니다T1업데이트 될 예정입니다. 추가 후CTID대상 목록에 실제로 쿼리 보이는 것 같습니다 :

t1.a, t2.b, t1.ctid t1, t2 여기서 t1.a = t2.a;를 선택하십시오.

이제 또 다른 세부 사항PostgreSQL무대에 들어갑니다. 오래된 테이블 행 덮어 쓰지 않았으며 이것이 이유입니다롤백빠릅니다. 에서업데이트, 새 결과 행이 삽입됩니다 테이블 (스트리핑 후CTID) 그리고 오래된 행의 행 헤드러에서CTID가리키는,cmaxandxmax항목입니다 현재 명령 카운터 및 현재 트랜잭션 ID로 설정하십시오. 따라서 오래된 행은 숨겨져 있고 거래 후 진공 청소기 클리너는 결국 죽은 줄을 제거 할 수 있습니다.

모든 것을 알고, 우리는 단순히 절대적으로보기 규칙을 적용 할 수 있습니다. 어떤 명령과 같은 방식. 차이가 없습니다.

38.2.3. 그만큼 의 견해의 힘PostgreSQL

상기는 규칙 시스템이보기를 통합하는 방법을 보여줍니다 원래 쿼리 트리에 대한 정의. 두 번째 예에서 a 단순한select한스포츠 토토 사이트에서 생성 된 a 4 개의 테이블에 결합 된 최종 쿼리 트리 (Unit다른 이름으로 두 번 사용되었습니다).

규칙 시스템으로 뷰를 구현하는 이점은 플래너는 어떤 테이블이어야하는지에 대한 모든 정보를 가지고 있습니다. 스캔 한 플러스이 테이블과 뷰의 제한적인 자격과 자격 하나의 단일 쿼리 트리의 원래 쿼리에서. 그리고 이것은 여전히입니다 원래 쿼리가 이미 뷰를 통해 가입 한 상황. 플래너는 쿼리 및 플래너가 더 많은 정보를 얻을수록 더 좋습니다. 결정이 될 수 있습니다. 그리고 구현 된 규칙 시스템PostgreSQL이것이 전부인지 확인합니다 그 시점까지 쿼리에 대한 정보.

38.2.4. 보기 업데이트

스포츠 토토 사이트가 AN의 대상 관계로 명명되면 어떻게됩니다삽입, 업데이트, 또는삭제? 대체를 수행합니다 위에서 설명한 쿼리 트리를 제공합니다. 하위 쿼리 테이블 항목에서의 관계 포인트는 그렇지 않습니다. 일하다. 몇 가지 방법이 있습니다PostgreSQL외관을 지원할 수 있습니다 그러나보기 업데이트.

하위 쿼리가 단일 기본 관계에서 선택하고 간단하게, 재 작성자는 하위 퀘스트를 자동으로 교체 할 수 있습니다 기본 기본 관계와 함께삽입, 업데이트또는삭제는 기본 관계에 적용됩니다 적절한 방법. 스포츠 토토 사이트"간단합니다 충분한"이것을.자동 업데이트 가능. 자세한 정보 자동으로 업데이트 될 수있는 관점의 종류에서 참조PostgreSQL : 문서.

또는 사용자가 제공하는 작업이 처리 될 수 있습니다대신스포츠 토토 사이트에서 트리거. 재 작성 이 경우 약간 다르게 작동합니다. 을 위한삽입, 다시 작성자는 전혀 아무것도하지 않습니다 스포츠 토토 사이트, 쿼리의 결과 관계로 남겨 두십시오. 을 위한업데이트삭제, 여전히스포츠 토토 사이트를 확장해야합니다 쿼리를 생산하는"Old"명령은 업데이트 또는 삭제를 시도합니다. 따라서보기가 확장됩니다 일반적이지만 또 다른 미지급 범위 테이블 항목이 추가됩니다. 결과적으로 용량의보기를 나타내는 쿼리 관계.

현재 발생하는 문제는 행을 식별하는 방법입니다. 보기에서 업데이트되었습니다. 결과 관계가 a 테이블, 특별CTIDEntry Is 대상 목록에 추가하여 물리적 위치를 식별합니다. 업데이트 할 행. 결과 관계가 보기에는보기에 아무것도 없기 때문에CTID, 행에는 실제가 없기 때문에 물리적 위치. 대신,업데이트또는삭제운영, 특별Wholerow항목은 대상 목록에 추가됩니다 스포츠 토토 사이트에서 모든 열을 포함하도록 확장합니다. 집행자가 사용합니다 공급하는이 값"Old"행으로 그만큼대신트리거. 그것은 닿습니다 이전 및 새 행을 기반으로 업데이트 할 내용을 해결하려면 트리거 값.

또 다른 가능성은 사용자가 정의하는 것입니다대신대체 조치를 지정하는 규칙삽입, 업데이트, 그리고삭제보기에 명령. 이 규칙 명령을 일반적으로 업데이트하는 명령으로 다시 작성합니다. 보기보다는 더 많은 테이블. 그것이의 주제입니다.섹션 38.4.

규칙이 먼저 평가되어 원본을 다시 작성합니다 쿼리가 계획되고 실행되기 전에 쿼리. 따라서보기에대신트리거 및 규칙에 대한삽입, 업데이트, 또는삭제그러면 규칙이 될 것입니다 먼저 평가했으며 결과에 따라 트리거가 전혀 사용해야합니다.

자동 재 작성삽입, 업데이트또는삭제간단한보기의 쿼리는 항상 마지막으로 시도됩니다. 그러므로보기라면 규칙이나 트리거가 있으면 기본 동작을 무시합니다. 자동으로 업데이트 가능한 뷰.

없는 경우대신규칙 또는대신보기를 트리거하고 Rewriter는 쿼리를 자동으로 다시 작성할 수 없습니다. 기본 기본 관계, 오류는 집행자는 뷰를 업데이트 할 수 없습니다.