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

17.2. 보기 및 스포츠 토토 결과 시스템

17.2.1. 에서의 뷰 구현Postgres

views inPostgresare 스포츠 토토 결과 시스템을 사용하여 구현되었습니다. 사실 절대적으로 있습니다 a의 차이 없음

mytab에서 myview를 선택하여 mytab;
두 명령과 비교
테이블 작성 myview (mytab과 같은 동일한 속성 목록);
    myview to myview 대신 스포츠 토토 결과 "_retmyview"를 작성하십시오.
        * mytab에서 * 선택;
이것이 바로 Create View 명령이하는 일이기 때문에 내부. 이것은 몇 가지 부작용이 있습니다. 그들 중 하나는 의 견해에 대한 정보Postgres시스템 카탈로그는 정확히 동일합니다 테이블과 마찬가지로. 따라서 쿼리 파서에는 절대적으로 있습니다 테이블과 뷰 사이에는 차이가 없습니다. 그들은 같은 것입니다 - 처지. 지금은 중요한 것입니다.

17.2.2. 어떻게 규칙 선택

SELECT의 스포츠 토토 결과은 마지막 단계로 모든 쿼리에 적용됩니다. 주어진 명령이 삽입, 업데이트 또는 삭제이더라도. 그리고 그들은 다른 사람들과 다른 의미를 가지고 있습니다. 새 제품을 만드는 대신 파트 세트를 제자리에 수정하십시오. 그래서 선택 스포츠 토토 결과은 먼저 설명됩니다.

현재, ON SELECT에는 하나의 조치 만있을 수 있습니다. 스포츠 토토 결과, 그리고 그것은 무조건 선택 행동이어야합니다. 대신에. 이 제한은 스포츠 토토 결과을 안전하게 만드는 데 필요했습니다 일반 사용자를 위해 열 수있을 정도로 충분하고 스포츠 토토 결과을 제한합니다. 실제보기 스포츠 토토 결과 선택.

이 문서의 예제는 두 가지 조인 뷰입니다. 일부 계산 및이를 사용하는 더 많은 견해. 하나 두 가지 첫 뷰 중에서 스포츠 토토 결과을 추가하여 나중에 사용자 정의됩니다. 최종 결과가되도록 작업을 삽입, 업데이트 및 삭제하십시오. 마법이있는 실제 테이블처럼 행동하는 견해가 될 것입니다. 기능. 시작하는 것은 그렇게 간단한 예가 아닙니다. 그리고 이것은 일을 어렵게 만듭니다. 그러나 더 낫습니다 단계별로 논의 된 모든 점을 다루는 예를 가지고 있습니다 섞일 수있는 많은 다른 것들을 갖기보다는 단계 명심.

예제를 사용하는 데 필요한 데이터베이스의 이름이 지정되었습니다. al_bundy. 이것이 왜 이것이 데이터베이스 이름인지 곧 알게 될 것입니다. 그리고 그것 우리는 절차 언어 pl/pgsql이 설치되어야합니다 작은 최소 () 기능이 필요합니다. 값. 우리는 그것을로 만듭니다.

기능 최소 (정수, 정수) 생성 정수를 반환합니다
        '시작하다
            $ 1 <$ 2 인 경우
                $ 1의 반환;
            끝 IF;
            $ 2를 반환합니다.
        끝;'
    언어 'plpgsql';

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

테이블 SHOE_DATA 만들기 (
        Shoename char (10) - 기본 키
        SH_AVAIL INTEGER - 사용 가능한 #
        Slcolor char (10) - 선호 된 떼 색상
        Slminlen float, -Miminum Shoelace 길이
        Slmaxlen float, - 최대 떼 길이
        Slunit char (8) - 길이 단위
    );

    테이블 생성 shoelace_data (
        SL_Name char (10), - 기본 키
        SL_AVAIL INTEGER, - 사용 가능한 #
        SL_COLOR char (10), - 떼 색상
        SL_LEN FLOAT, - 신발성 길이
        SL_UNIT char (8) - 길이 단위
    );

    테이블 장치 생성 (
        un_name char (8) - 기본 키
        un_fact float- cm으로 변환하는 요소
    );
나는 우리 대부분이 신발을 입는다 고 생각하며 이것이 정말 유용한 데이터. 글쎄, 세상에는 신발이 있습니다 신발락이 필요하지 않지만 Al의 삶이 더 쉬워지지는 않으며 그래서 우리는 그것을 무시합니다.

보기는로 생성됩니다.

보기 신발을 만듭니다
        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;
Shoelace보기 (우리가 가진 가장 간단한 것입니다) 관계 떼와 항목을 생성합니다pg_rewrite재 작성 스포츠 토토 결과이 있음을 알려줍니다 관계 떼가 참조 될 때마다 적용해야합니다. 쿼리의 rangetable에서. 스포츠 토토 결과에는 스포츠 토토 결과 자격이 없습니다 (선택 스포츠 토토 결과 이후 비 선택 스포츠 토토 결과과 나중에 논의 현재는 가질 수 없습니다) 대신입니다. 그 스포츠 토토 결과에 유의하십시오 자격은 쿼리 자격과 같지 않습니다! 스포츠 토토 결과 조치에는 쿼리 자격이 있습니다.

스포츠 토토 결과의 조치는 하나의 쿼리 트리입니다. View Creation Command에서 명령문을 선택하십시오.

참고 :새로운 2 개의 추가 범위 테이블 항목 그리고 오래된 ( * New * 및 * Current *) 역사적 이유로 인쇄 된 querytree)에서에서 볼 수 있습니다.pg_rewrite입장은 관심이 없습니다 스포츠 토토 결과 선택.

이제 우리는 포기Unit, Shoe_dataandshoelace_data및 Al 유형의 첫 번째 선택을 입력합니다 그의 삶 :
al_bundy = 단위 값에 삽입 ( 'cm', 1.0);
    al_bundy = 단위 값에 삽입 ( 'm', 100.0);
    al_bundy = 단위 값에 삽입 ( '인치', 2.54);
    al_bundy = 
    al_bundy = Shoe_Data 값에 삽입하십시오 
    al_bundy- ( 'sh1', 2, 'black', 70.0, 90.0, 'cm');
    al_bundy = Shoe_Data 값에 삽입하십시오 
    al_bundy- ( 'sh2', 0, 'black', 30.0, 40.0, 'inch');
    al_bundy = Shoe_Data 값에 삽입하십시오 
    al_bundy- ( 'sh3', 4, 'brown', 50.0, 65.0, 'cm');
    al_bundy = Shoe_Data 값에 삽입하십시오 
    al_bundy- ( 'sh4', 3, 'brown', 40.0, 50.0, 'inch');
    al_bundy = 
    al_bundy = shoelace_data 값에 삽입하십시오 
    al_bundy- ( 'sl1', 5, 'black', 80.0, 'cm');
    al_bundy = shoelace_data 값에 삽입하십시오 
    al_bundy- ( 'sl2', 6, 'black', 100.0, 'cm');
    al_bundy = shoelace_data 값에 삽입하십시오 
    al_bundy- ( 'sl3', 0, 'black', 35.0, 'inch');
    al_bundy = shoelace_data 값에 삽입하십시오 
    al_bundy- ( 'sl4', 8, 'black', 40.0, 'inch');
    al_bundy = shoelace_data 값에 삽입하십시오 
    al_bundy- ( 'sl5', 4, 'brown', 1.0, 'm');
    al_bundy = shoelace_data 값에 삽입하십시오 
    al_bundy- ( 'sl6', 0, 'brown', 0.9, 'm');
    al_bundy = shoelace_data 값에 삽입하십시오 
    al_bundy- ( 'sl7', 7, 'brown', 60, 'cm');
    al_bundy = shoelace_data 값에 삽입하십시오 
    al_bundy- ( 'sl8', 1, 'brown', 40, 'inch');
    al_bundy = 
    al_bundy = select *에서 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 줄)
우리의 견해에 대해 AL이 할 ​​수있는 가장 간단한 선택이므로 우리는 이것은보기 규칙의 기본 사항을 설명하기 위해. 'select * from Shoelace '는 파서에 의해 해석되었고 파 세트를 생산했습니다
shoelace.sl_name, shoelace.sl_avail 선택을 선택하십시오.
           shoelace.sl_color, shoelace.sl_len,
           shoelace.sl_unit, shoelace.sl_len_cm
      Shoelace Shoelace에서;
그리고 이것은 스포츠 토토 결과 시스템에 제공됩니다. 스포츠 토토 결과 시스템이 걷는다 Rangetable을 통해 및 스포츠 토토 결과이 있는지 확인합니다pg_rewrite모든 관계. 언제 rangetable 항목 처리Shoelace(지금까지 유일한 사람)는 그것을 찾습니다 Parsetree와 함께 스포츠 토토 결과 '_retshoelace'
    S.SL_NAME, S.SL_AVAIL, SELECT SELECT
           s.sl_color, s.sl_len, s.sl_unit,
           sl_len_cm으로 float8mul (s.sl_len, u.un_fact)
      Shoelace *Old *, Shoelace *New *,
           shoelace_data s, 단위 u
     여기서 bpchareq (s.sl_unit, u.un_name);
파서가 계산을 변경했습니다 적절한 기능에 대한 호출 자격. 그러나 사실 이것은 아무것도 바뀌지 않습니다.

보기를 확장하려면 다시 작성자는 단순히 subselect를 만듭니다. 규칙의 조치 파 세트를 포함하는 rangetable 항목 및 이 순종 할 수없는 항목을 원래 항목으로 대체합니다 견해를 참조했습니다. 결과적으로 다시 작성된 파 세트는 다음과 같습니다 Al이 입력 한 것처럼 거의

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;
그러나 한 가지 차이점이 있습니다 : 하위 쿼리의 rangetable 두 개의 추가 항목이 있습니다. 이 항목 쿼리에 직접 참여하지 않으므로 그렇지 않습니다 하위 쿼리의 Join Tree 또는 TargetList에 의해 참조됩니다. 재 작성자 그것들을 사용하여 액세스 권한 확인 확인 정보를 저장합니다. 원래 The를 언급 한 Rangetable 항목에 존재합니다 보다. 이런 식으로, 집행 인은 여전히 ​​사용자가 없더라도보기에 액세스 할 수있는 적절한 권한 다시 쓰기 쿼리에서보기를 직접 사용합니다.

그것은 첫 번째 규칙이 적용되었습니다. 스포츠 토토 결과 시스템이 있습니다 상단에 나머지 rangetable 항목을 계속 확인하십시오 쿼리 (이 예에서는 더 이상 없음). 추가 된 하위 쿼리에서 rangetable 항목을 재귀 적으로 확인하십시오 참조 뷰가 있는지 확인합니다. (그러나 확장되지는 않습니다 * old* 또는* new* --- 그렇지 않으면 우리는 무한 재귀가있을 것입니다!) 이 예, Shoelace_data에 대한 재 작성 규칙이 없습니다. 단위, 재 작성이 완료되고 위의 것은 최종입니다. 플래너에게 주어진 결과.

이제 우리는 Blues Brothers의 문제에 직면합니다. 그의 가게에 나타나 새 신발을 사고 싶어 블루스 브라더스는 같은 신발을 신고 싶어합니다. 그리고 그것들 즉시 착용하고 싶어서 신발이 필요합니다.

al은 현재 상점에 어떤 신발을 알아야합니다 일치하는 신발 (색상 및 크기)과 총계가 있습니다. 정확히 일치하는 쌍의 수는 두 개 또는 동일합니다. 우리 그에게 무엇을 해야하는지 가르쳐주고 데이터베이스를 묻습니다.

al_bundy = SELECT *에서 SHOE_READY where total_avail = 2;
    shoename | sh_avail | sl_name | sl_avail | Total_avail
    ----------+--------+----------+-------+----------
    sh1 |       2 | SL1 |       5 |          2
    sh3 |       4 | SL7 |       7 |          4
    (2 줄)
al은 신발 전문가이며 Sh1 유형의 신발 만 알고 있습니다. 적합합니다 (Shoelace SL7은 갈색이고 갈색이 필요한 신발입니다. 신발은 신발이 아닙니다. Blues Brothers가 입을 수있는 신발).

파서의 출력은 이번에는 파 세트입니다

shoe_ready.shoename, 슈 _ready.sh_avail,
           shoe_ready.sl_name, shoe_ready.sl_avail,
           Shoe_ready.total_avail
      Shoe_ready Shoe_ready에서
     여기서 int4ge (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
     여기서 int4ge (shoe_ready.total_avail, 2);
마찬가지로, 스포츠 토토 결과신발andShoelace하위 쿼리의 순수성, 3 단계 결승전으로 이어집니다 querytree :
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
     여기서 int4ge (shoe_ready.total_avail, 2);
플래너 가이 나무를 2 레벨 쿼리 트리 : 병적 인 Selects는 "풀링"됩니다. 중간 선택을 처리 할 필요가 없으므로 갈라져. 그러나 중간 선택은 총 기능이 포함되어 있기 때문에 상단. 우리가 그것들을 끌어 당겼다면 그것은 우리가하지 않는 최상위 선택의 동작을 바꿀 것입니다. 원하다. 그러나 쿼리 트리를 무너 뜨리는 것은 최적화입니다 재 작성 시스템은 스스로 관심을 가질 필요가 없습니다.

참고 :현재 재귀 중지는 없습니다 스포츠 토토 결과 시스템에서보기 규칙을위한 메커니즘 ( 다른 종류의 규칙). 이것은 크게 아프지 않습니다 이것을 끝없는 루프로 밀어 넣는 유일한 방법 ( 메모리 제한에 도달 할 때까지 백엔드) 테이블을 작성한 다음 Create와 함께 수작업으로보기 규칙을 설정하십시오. 그러한 방식으로, 하나는 다른 하나에서 선택합니다. 하나에서 선택합니다. 생성하면 결코 일어날 수 없습니다 뷰는 첫 번째 생성보기에 대해 사용됩니다. 관계는 존재하지 않으므로 첫 번째 견해는 두 번째에서 선택하십시오.

17.2.3. 보다 비 선택적 진술의 규칙

Parsetree의 두 가지 세부 사항은 다음과 같습니다 위의보기 규칙에 대한 설명. 이것들은 CommandType입니다 결과적으로. 실제로, 규칙은 이것을 필요로하지 않습니다 정보.

다른 명령을 선택하고 하나를 선택하십시오. 분명히 그들은 가지고 있습니다 또 다른 CommandType와 이번에는 결과가 향상됩니다 결과가 나가야하는 순수한 항목. 모든 것 그렇지 않으면 절대적으로 동일합니다. 따라서 두 개의 테이블 T1과 T2가 있습니다 속성 A와 B를 사용하여 두 사람의 ParsetRees 진술

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

    T1 Set B = T2.B 업데이트 여기서 T1.A = T2.A;
거의 동일합니다.
  • rangetables에는 테이블 t1 및 T2.

  • TargetList에는 하나의 변수가 포함되어 있습니다 표 T2에 대한 rangetable 항목의 속성 B.

  • 자격 표현식은 속성을 비교합니다 평등을위한 두 범위 중.

  • Jointrees는 T1과 T2 사이의 간단한 결합을 보여줍니다.

결과는 두 파수의 두 가지가 비슷한 결과를 초래한다는 것입니다 실행 계획. 둘 다 두 테이블에 합류합니다. 을 위한 T1의 누락 된 열이 업데이트됩니다. Planner의 TargetList와 최종 파 세트는로 읽습니다.
업데이트 t1 설정 a = t1.a, b = t2.b 여기서 t1.a = t2.a;
따라서 Executor는 가입을 통해 달리기가 정확히 생성됩니다. 동일한 결과 세트 A
t1.a, t2.b에서 t1.a = t2.a;에서 t1.a, t2.b를 선택하십시오.
그러나 업데이트에는 약간의 문제가 있습니다. 그만큼 집행자는 가입의 결과가 무엇을하는지 신경 쓰지 않습니다. 의미합니다. 결과는 단지 결과 집합을 생성합니다. 그만큼 하나는 선택 명령이고 다른 하나는 업데이트입니다. 집행자의 발신자로 처리됩니다. 발신자는 여전히 알고 있습니다 (Parsetree를보고) 이것이 업데이트라는 것을 알고 있습니다. 이 결과는 표 T1로 들어가야합니다. 그러나 어느 행입니다 새로운 행으로 대체되어야합니까?

이 문제를 해결하려면 다른 항목이 추가됩니다. Update (및 Delete)의 TargetList : the 현재 튜플 ID (CTID). 이것은 시스템 속성을 포함합니다 행의 블록의 파일 블록 번호와 위치. 테이블을 알면 CTID는 업데이트 할 원본 T1 행입니다. CTID를 추가 한 후 TargetList, 쿼리는 실제로

t1.a, t2.b, t1.ctid에서 t1, t2에서 t1.a = t2.a;를 선택하십시오.
이제 또 다른 세부 사항Postgres무대에 들어갑니다. 지금은 테이블 행을 덮어 쓰지 않으므로 이것이 중단 된 거래입니다. 빠른. 업데이트에서 새 결과 행이 테이블에 삽입됩니다. (CTID 스트리핑 후) 및 그 행의 튜플 헤더에서 CTID CMAX를 가리키고 Xmax 항목이 현재 명령으로 설정됩니다. 카운터 및 현재 트랜잭션 ID. 따라서 오래된 행은 숨겨져 있습니다 거래가 헌신 한 후 진공 청소기는 실제로 움직일 수 있습니다. it.

모든 것을 알고, 우리는 단순히보기 스포츠 토토 결과을 적용 할 수 있습니다. 어떤 명령과 같은 방식으로. 아니요 차이점.

17.2.4. 그만큼 의 견해의 힘Postgres

상기는 스포츠 토토 결과 시스템이보기를 통합하는 방법을 보여줍니다 원래 파 세트로 정의. 두 번째 예에서 One View에서 간단한 선택은 최종 파 세트를 생성했습니다. 4 개의 테이블 조인 (단위는 다른 두 번 사용됩니다. 이름).

17.2.4.1. 이익

스포츠 토토 결과 시스템으로 뷰를 구현하는 이점은 다음과 같습니다. 플래너가 어떤 테이블에 대한 모든 정보를 가지고 있음 스캔해야합니다 테이블과보기의 제한적인 자격 또한 원본 쿼리의 자격은 하나의 싱글 파 세트. 그리고 이것은 여전히 ​​원본이 될 때입니다 쿼리는 이미 조회수에 대한 가입입니다. 이제 플래너는해야합니다 쿼리를 실행하는 가장 좋은 경로를 결정하십시오. 더 플래너의 정보는이 결정이 더 좋을 수 있습니다. 그리고 구현 된 스포츠 토토 결과 시스템Postgres이것이 전부인지 확인합니다 지금까지 쿼리에 대한 정보가 제공됩니다.

17.2.5. 무엇 보기 업데이트에 대해?

보기가 대상 관계로 지명되면 어떻게되는지 삽입, 업데이트 또는 삭제? 대체 후 위에서 설명한 경우, 우리는 하위 퀘스트 가능한 항목의 결과 지점. 이것은 할 것입니다 작동하지 않으므로 다시 작성자가 오류가 발생하면 오류가 발생합니다. 그런 일을 제작했습니다.

이것을 변경하려면 동작을 수정하는 규칙을 정의 할 수 있습니다. 비 선택적 쿼리. 이것이 다음 주제입니다 부분.