이 문서는 지원되지 않는 버전의 PostgreSQL 용입니다.
당신은에 대해 같은 페이지를 볼 수 있습니다메이저 토토 핫 사이트 PostgreSQL : 문서 : 17 : 5.12. 테이블 파티셔닝버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

5.12. 토토 핫 파티셔닝#

postgresql기본 토토 핫 파티셔닝을 지원합니다. 이 섹션에서는 데이터베이스 디자인의 일부로 파티셔닝을 구현하는 이유와 방법에 대해 설명합니다.

5.12.1. 개요#

토토 핫은 논리적으로 하나의 큰 테이블을 작은 물리적 조각으로 분할하는 것을 말합니다. 분할은 몇 가지 이점을 제공 할 수 있습니다.

  • 특히 테이블의 많은 액세스 행이 단일 토토 핫 또는 소수의 토토 핫에있을 때 특정 상황에서 쿼리 성능을 크게 향상시킬 수 있습니다. 분할은 상위 트리 수준의 인덱스 레벨을 효과적으로 대체하여 인덱스의 무겁게 사용되는 부분이 메모리에 적합 할 가능성이 높아집니다.

  • 쿼리 또는 업데이트가 단일 토토 핫의 많은 비율에 액세스 할 때 인덱스를 사용하는 대신 해당 토토 핫의 순차적 스캔을 사용하여 성능을 향상시킬 수 있습니다.

  • 토토 핫 디자인에서 사용 패턴이 설명되면 토토 핫을 추가하거나 제거하여 벌크 하중 및 삭제를 수행 할 수 있습니다. 사용을 사용하여 개별 토토 핫 삭제드롭 토토 핫또는 행동Alter Table Detach Partition, 대량 작동보다 훨씬 빠릅니다. 이 명령은 또한 전적으로를 피합니다.진공벌크로 인한 오버 헤드삭제.

  • 거의 사용하지 않는 데이터를 저렴하고 느린 스토리지 미디어로 마이그레이션 할 수 있습니다.

이러한 혜택은 일반적으로 토토 핫이 매우 큰 경우에만 가치가 있습니다. 토토 핫의 크기가 데이터베이스 서버의 물리적 메모리를 초과해야한다는 것입니다.

postgresql다음 형식의 파티셔닝에 대한 내장 지원을 제공합니다.

범위 파티셔닝 #

토토 핫이 분할되어범위다른 토토 핫에 할당 된 값의 범위간에 겹치지 않고 키 열 또는 열 세트로 정의됩니다. 예를 들어, 날짜 범위 또는 특정 비즈니스 오브젝트에 대한 식별자 범위별로 분할 할 수 있습니다. 각 범위의 범위는 하단에 포괄적이며 상단에 독점적으로 이해됩니다. 예를 들어, 한 토토 핫의 범위가 인 경우1to10, 그리고 다음 사람의 범위는입니다.10to20, value10첫 번째가 아닌 두 번째 토토 핫에 속합니다.

파티셔닝 목록 #

테이블은 각 토토 핫에 어떤 키 값이 나타나는지 명시 적으로 나열하여 분할됩니다.

해시 파티셔닝 #

테이블은 각 토토 핫에 대한 계수와 나머지를 지정하여 분할됩니다. 각 토토 핫은 토토 핫 키의 해시 값이 지정된 계수로 나뉘어지는 행을 지정된 나머지를 생성합니다.

응용 프로그램이 위에 나열되지 않은 다른 형태의 파티셔닝을 사용해야하는 경우 상속 및와 같은 대체 방법.Union All대신보기를 사용할 수 있습니다. 이러한 방법은 유연성을 제공하지만 내장 선언 파티셔닝의 성능 이점은 없습니다.

5.12.2. 선언적 분할#

postgresql테이블이 토토 핫으로 나뉘어 있다고 선언 할 수 있습니다. 나뉘어 진 테이블을라고합니다.토토 핫 테이블. 선언에는가 포함됩니다.토토 핫 방법위에서 설명한대로,토토 핫 키.

분할 된 토토 핫 자체는 A입니다.Virtual자체 저장 장치가없는 토토 핫. 대신, 스토리지는에 속합니다.토토 핫는 분할 된 테이블과 관련된 다른 표지 테이블입니다. 각 토토 핫은 데이터의 하위 집합을 저장합니다.토토 핫 경계. 토토 핫 된 테이블에 삽입 된 모든 행은 토토 핫 키 열의 값을 기반으로 적절한 토토 핫 중 하나로 라우팅됩니다. 행의 토토 핫 키를 업데이트하면 원래 토토 핫의 토토 핫 한계를 더 이상 만족하지 않으면 다른 토토 핫으로 이동합니다.

토토 핫 자체는 토토 핫 된 테이블로 정의되어하위 분수. 모든 토토 핫은 분할 된 부모와 동일한 열을 가져야하지만, 토토 핫에는 자체 인덱스, 제약 조건 및 기본값이 다른 토토 핫과는 별개가있을 수 있습니다. 보다토토 핫 생성토토 핫 된 테이블 및 토토 핫 작성에 대한 자세한 내용은

일반 테이블을 토토 핫 된 테이블 또는 그 반대로 바꿀 수 없습니다. 그러나 기존 정규 또는 분할 된 테이블을 분할 된 테이블의 토토 핫으로 추가하거나 토토 핫 된 테이블에서 토토 핫을 독립형 테이블로 전환 할 수 있습니다. 이것은 많은 유지 보수 프로세스를 단순화하고 속도를 높일 수 있습니다. 보다Alter Table에 대해 자세히 알아 보려면토토 핫 첨부and분리하위 명령.

토토 핫도 가능합니다PostgreSQL : 문서 : 18 : 5.13. 외국 메이저 토토 핫 사이트, 외국 토토 핫의 내용이 분할 규칙을 충족시키는 것은 사용자의 책임이기 때문에 상당한주의가 필요합니다. 다른 제한 사항도 있습니다. 보다PostgreSQL :자세한 내용은

5.12.2.1. 예#

우리가 대형 아이스크림 회사의 데이터베이스를 구성한다고 가정 해 봅시다. 이 회사는 매일 최대 온도를 측정하고 각 지역의 아이스크림 판매를 측정합니다. 개념적으로 우리는 다음과 같은 토토 핫을 원합니다.

토토 핫 측정 생성 (
    city_id int null not,
    로그 데이트 날짜는 null이 아닙니다.
    PeakTemp int,
    단위 int
);

우리는 대부분의 쿼리가 지난 주, 월 또는 분기 데이터에만 액세스 할 것임을 알고 있습니다.이 표의 주요 사용은 관리를위한 온라인 보고서를 준비하는 것이기 때문입니다. 저장 해야하는 이전 데이터의 양을 줄이기 위해 가장 최근 3 년간의 데이터 만 유지하기로 결정했습니다. 매월 초에 우리는 가장 오래된 달의 데이터를 제거합니다. 이 상황에서 우리는 파티셔닝을 사용하여 측정 토토 핫에 대한 다양한 요구 사항을 충족 할 수 있습니다.

이 경우 선언 파티셔닝을 사용하려면 다음 단계를 사용하십시오.

  1. 생성측정토토 핫을 지정하여 분할 된 토토 핫로 토토 핫토토 핫 by절단 방법 (를 포함합니다.범위이 경우) 및 토토 핫 키로 사용할 열 목록.

    테이블 측정 생성 (
        city_id int null not,
        로그 데이트 날짜는 null이 아닙니다.
        PeakTemp int,
        단위 int
    ) 범위 별 토토 핫 (logdate);
  2. 토토 핫 생성. 각 토토 핫의 정의는 부모의 분할 방법 및 토토 핫 키에 해당하는 경계를 지정해야합니다. 새로운 토토 핫의 값이 하나 이상의 기존 토토 핫의 값과 겹치도록 경계를 지정하면 오류가 발생합니다.

    이렇게 생성 된 토토 핫은 모든면에서 정상입니다PostgreSQL테이블 (또는 아마도 외국 테이블). 각 토토 핫에 대한 테이블 스페이스 및 스토리지 매개 변수를 별도로 지정할 수 있습니다.

    이 예를 들어, 각 토토 핫은 한 달에 한 달에 한 달에 한 달의 데이터를 삭제 해야하는 요구 사항과 일치하도록 한 달에 달하는 데이터를 보유해야합니다. 그래서 명령은 다음과 같습니다 :

    테이블 측정 생성 _y2006m02 측정의 토토 핫
        ( '2006-02-01')에서 ( '2006-03-01')의 값;
    
    테이블 측정 _y2006m03 측정의 토토 핫을 만듭니다
        ( '2006-03-01')에서 ( '2006-04-01')의 값;
    
    ...
    테이블 측정 _y2007m11 측정의 토토 핫을 만듭니다
        ( '2007-11-01')에서 ( '2007-12-01')의 값;
    
    테이블 측정 _y2007m12 측정의 토토 핫을 만듭니다
        ( '2007-12-01')에서 ( '2008-01-01')의 값
        테이블 스페이스 FastTablespace;
    
    테이블 측정 _y2008m01 측정의 토토 핫을 만듭니다
        ( '2008-01-01')에서 ( '2008-02-01')의 값
        with (parallel_workers = 4)
        테이블 스페이스 FASTTABLESPACE;

    (인접한 토토 핫은 범위 상한이 배타적 경계로 취급되므로 경계 값을 공유 할 수 있음을 기억합니다.)

    하위 파티셔닝을 구현하려면 다시 지정하십시오토토 핫 by개별 토토 핫을 작성하는 데 사용되는 명령의 조항 :

    테이블 측정 생성 _y2006M02 측정의 토토 핫
        ( '2006-02-01')에서 ( '2006-03-01')의 값
        범위 별 토토 핫 (PeakTemp);

    토토 핫을 작성한 후측정 _y2006m02,에 삽입 된 모든 데이터측정그에 매핑되었습니다측정 _y2006m02(또는 직접 삽입되는 데이터측정 _y2006m02, 토토 핫 제약 조건이 충족되면 허용됩니다.)PeakTemp열. 지정된 토토 핫 키는 부모의 토토 핫 키와 겹칠 수 있지만, 부착물의 한계를 지정할 때주의를 기울여야합니다. 시스템은 그것이 실제로 사실인지 확인하려고하지 않습니다.

    기존 토토 핫 중 하나에 맵핑되지 않는 상위 테이블에 데이터를 삽입하면 오류가 발생합니다. 적절한 토토 핫을 수동으로 추가해야합니다.

    토토 핫의 토토 핫 경계 조건을 설명하는 테이블 제약 조건을 수동으로 생성 할 필요는 없습니다. 이러한 제약은 자동으로 생성됩니다.

  3. 토토 핫 된 테이블에서 키 열 (들)과 원하는 다른 색인에 인덱스를 만듭니다. (주요 인덱스는 엄격하게 필요하지 않지만 대부분의 시나리오에서는 도움이됩니다.) 이것은 각 토토 핫에 일치하는 인덱스를 자동으로 생성하며 나중에 생성하거나 첨부하는 토토 핫도 그러한 인덱스를 갖습니다. 분할 된 테이블에 선언 된 색인 또는 고유 한 제약 조건은입니다.Virtual분할 된 테이블과 같은 방식으로 : 실제 데이터는 개별 토토 핫 테이블의 하위 인덱스에 있습니다.

    측정에서 색인 생성 (logdate);
  4. enable_partition_pruning구성 매개 변수가 비활성화되지 않았습니다postgresql.conf. 그렇다면 쿼리는 원하는대로 최적화되지 않습니다.

위의 예에서는 매달 새 토토 핫을 만들 것이므로 필요한 DDL을 자동으로 생성하는 스크립트를 작성하는 것이 현명 할 수 있습니다..

5.12.2.2. 토토 핫 유지 보수#

일반적으로 테이블을 처음 정의 할 때 설정된 토토 핫 세트는 정적을 유지하기위한 것이 아닙니다. 이전 데이터를 보유한 토토 핫을 제거하고 정기적으로 새로운 데이터에 새로운 토토 핫을 추가하는 것이 일반적입니다. 파티셔닝의 가장 중요한 장점 중 하나는 많은 양의 데이터를 물리적으로 움직이지 않고 토토 핫 구조를 조작 하여이 고통스러운 작업을 거의 즉시 실행할 수 있다는 것입니다..

오래된 데이터를 제거하기위한 가장 간단한 옵션은 더 이상 필요하지 않은 토토 핫을 삭제하는 것입니다.

드롭 토토 핫 측정 _y2006m02;

이것은 모든 레코드를 개별적으로 삭제할 필요가 없기 때문에 수백만 레코드를 매우 빠르게 삭제할 수 있습니다. 그러나 위의 명령은액세스 독점부모 토토 핫의 잠그십시오.

종종 바람직한 또 다른 옵션은 토토 핫 된 테이블에서 토토 핫을 제거하지만 그 자체의 테이블로 액세스 할 수있는 것입니다. 이것은 두 가지 형태가 있습니다 :

ALTER 테이블 측정 분리 토토 핫 측정 _Y2006M02;
ALTER TABLE 측정 분리 토토 핫 측정 _Y2006M02 동시에;

이를 통해 데이터가 삭제되기 전에 추가 작업을 수행 할 수 있습니다. 예를 들어, 이것은 종종를 사용하여 데이터를 백업하는 데 유용한 시간입니다.copy, pg_dump또는 유사한 도구. 또한 데이터를 더 작은 형식으로 집계하거나 다른 데이터 조작을 수행하거나 보고서를 실행하는 데 유용한 시간 일 수도 있습니다. 명령의 첫 번째 형태에는가 필요합니다.액세스 독점부모 토토 핫을 잠그십시오. 추가동시에두 번째 양식에서와 같은 예선은 분리 작업이 필요합니다공유 업데이트 독점부모 토토 핫을 잠그지 만 참조Alter Table ... 분리 토토 핫제한에 대한 자세한 내용.

마찬가지로 새로운 데이터를 처리하기 위해 새 토토 핫을 추가 할 수 있습니다. 위에 원래 토토 핫이 생성 된 것처럼 토토 핫 된 테이블에서 빈 토토 핫을 만들 수 있습니다.

테이블 측정 생성 _y2008m02 측정의 토토 핫
    ( '2008-02-01')에서 ( '2008-03-01')의 값
    테이블 스페이스 FASTTABLESPACE;

새 토토 핫을 만드는 대안으로서, 토토 핫 구조와 별개의 새 테이블을 만들고 나중에 토토 핫으로 첨부하는 것이 더 편리합니다. 이를 통해 토토 핫 된 테이블에 나타나기 전에 새 데이터를로드, 점검 및 변환 할 수 있습니다. 또한첨부 토토 핫작동 만 필요합니다공유 업데이트 독점|액세스 독점잠금 요구에 의해토토 핫 생성 ... 토토 핫, 따라서 토토 핫 된 테이블의 동시 작업에 더 친숙합니다. 보다Alter Table ... 첨부 토토 핫추가 세부 사항. 그만큼토토 핫 생성 ... 좋아요옵션은 부모 토토 핫의 정의를 지식으로 반복하는 것을 피하는 데 도움이 될 수 있습니다. 예를 들어:

테이블 측정 생성 _y2008m02
  (제약 조건을 포함한 기본값을 포함한 측정과 같은)
  테이블 스페이스 FastTablespace;

Alter Table Measurement_Y2008M02 추가 제약 조건 Y2008M02
   check (logdate = date '2008-02-01'및 logdate <날짜 '2008-03-01');

\ '측정 _y2008m02'에서 측정 _y2008m02 복사
- 아마도 다른 데이터 준비 작업

알터 테이블 측정 첨부 토토 핫 측정 _y2008m02
    ( '2008-02-01')에서 ( '2008-03-01');의 값

실행할 때첨부 토토 핫명령에 따라 테이블이 스캔되어 토토 핫 제약 조건을 유지하는 동안액세스 독점해당 토토 핫을 잠그십시오. 위에서 볼 수 있듯이 a를 만들어이 스캔을 피하는 것이 좋습니다.check제약 조건을 첨부하기 전에 테이블의 예상되는 토토 핫 제약 조건과 일치합니다. 일단토토 핫 첨부완료되었으므로 현재 중복을 삭제하는 것이 좋습니다check제약. 첨부중인 테이블 자체가 토토 핫 된 테이블이라면, 각 하위 토토 핫은 적절한 상태가 될 때까지 재귀 적으로 잠그고 스캔됩니다check제약 조건이 발생하거나 잎 토토 핫에 도달합니다.

마찬가지로, 분할 된 토토 핫에 A가있는 경우기본토토 핫, a를 만드는 것이 좋습니다check상충되는 토토 핫의 제약을 제외하는 제약 조건. 이 작업이 완료되지 않으면기본값토토 핫은 첨부 된 토토 핫에 위치 해야하는 레코드가 포함되어 있는지 확인하기 위해 스캔됩니다. 이 작업은 AN을 유지하는 동안 수행됩니다액세스 독점잠금기본값토토 핫. 인 경우기본값토토 핫 자체는 토토 핫 된 테이블이며, 각 토토 핫은 위에서 언급 한 것처럼 테이블이 첨부되는 테이블과 동일한 방식으로 재귀 적으로 체크인됩니다..

앞에서 언급했듯이, 전체 계층에 자동으로 적용되도록 분할 된 테이블에 인덱스를 생성 할 수 있습니다. 기존의 모든 토토 핫이 색인화 될뿐만 아니라 향후 토토 핫도 마찬가지이므로 매우 편리 할 수 있습니다. 그러나 토토 핫 된 테이블에서 새 인덱스를 생성 할 때 한 가지 제한 사항은를 사용할 수 없다는 것입니다.동시에예선은 잠금 시간이 길어질 수 있습니다. 이를 피하려면 사용할 수 있습니다index on in토토 핫 된 테이블은 유효하지 않은 새 인덱스를 생성하여 기존 토토 핫에 대한 자동 응용 프로그램을 방지합니다. 대신, 인덱스는를 사용하여 각 토토 핫에서 개별적으로 생성 될 수 있습니다.동시에and첨부|ALTER INDEX ... 토토 핫 첨부. 모든 토토 핫에 대한 인덱스가 상위 색인에 첨부되면 부모 색인이 자동으로 유효합니다. 예:

만 인덱스 측정 _USLS_IDX 생성 (단위);

인덱스를 동시에 측정 _usls_200602_idx를 만듭니다
    측정 _y2006m02 (유니 세계);
Alter Index Measurement_usls_idx
    토토 핫 측정 _USLS_200602_IDX 첨부;
...

이 기술은와 함께 사용할 수 있습니다.고유 한기본 키제약 조건도; 제약 조건이 생성 될 때 인덱스가 암시 적으로 생성됩니다. 예:

ALTER TABLE 전용 측정 추가 고유 (City_ID, Logdate);

Alter Table Measurement_Y2006M02 고유 한 추가 (City_id, Logdate);
ALTER Index Measurement_City_ID_LOGDATE_KEY
    토토 핫 측정 _Y2006M02_CITY_ID_LOGDATE_KEY 첨부;
...

5.12.2.3. 제한#

다음 한계는 분할 된 토토 핫에 적용됩니다 :

  • 토토 핫 된 테이블에 고유 또는 기본 키 제약 조건을 생성하려면 토토 핫 키에는 표현식 또는 기능 호출이 포함되어서는 안되며 제약 조건의 열에는 모든 토토 핫 키 열에 포함되어야합니다. 이러한 제한은 제약 조건을 구성하는 개별 지수가 자신의 토토 핫 내에서만 독창성을 직접적으로 시행 할 수 있기 때문에 존재합니다. 따라서 토토 핫 구조 자체는 다른 토토 핫에 복제가 없음을 보장해야합니다.

  • 마찬가지로 제외 제약 조건에는 모든 토토 핫 키 열이 포함되어야합니다. 또한 제약 조건은 해당 열을 평등과 비교해야합니다 (예 :&&). 다시 말하지만,이 제한은 교차 토토 핫 제한을 시행 할 수 없다는 것입니다. 제약 조건에는 토토 핫 키의 일부가 아닌 추가 열이 포함될 수 있으며 원하는 작업자와 비교할 수 있습니다..

  • 전 행트리거 on삽입새로운 행의 최종 대상이 어떤 토토 핫을 변경할 수 없습니다.

  • 동일한 토토 핫 트리에서 임시 및 영구 관계를 믹싱하는 것은 허용되지 않습니다. 따라서 분할 된 테이블이 영구적 인 경우, 토토 핫이어야하며 마찬가지로 분할 된 테이블이 임시 인 경우 마찬가지로. 임시 관계를 사용할 때는 토토 핫 트리의 모든 구성원이 같은 세션에서 나와야합니다.

개별 토토 핫은 상속 비하인드 스토리를 사용하여 분할 된 테이블에 연결됩니다. 그러나 아래에서 논의 된 바와 같이 선언적으로 분할 된 테이블 또는 토토 핫과 함께 상속의 모든 일반적인 특징을 사용할 수는 없습니다. 특히, 토토 핫은 토토 핫 된 테이블 이외의 부모를 가질 수 없으며, 토토 핫 된 테이블과 일반 테이블 모두에서 테이블을 상속받을 수 없습니다. 즉, 토토 핫 된 테이블과 토토 핫은 상속 계층을 일반 테이블과 공유하지 않습니다.

토토 핫 된 테이블과 그 토토 핫으로 구성된 토토 핫 계층이 여전히 상속 계층,이므로Tableoid및 모든 일반적인 상속 규칙이에 적용됩니다토토 핫 PostgreSQL : 문서 : 18 : 5.11. 계승, 몇 가지 예외가 있습니다 :

  • 토토 핫에는 부모에 존재하지 않는 열을 가질 수 없습니다. 로 토토 핫을 생성 할 때 열을 지정할 수 없습니다토토 핫 생성Alter Table. 테이블은와 토토 핫으로 추가 될 수 있습니다.ALTER 테이블 ... 토토 핫 첨부열이 부모와 정확히 일치하는 경우에만.

  • 둘 다checkandNOT NULL분할 된 테이블의 제약은 항상 모든 토토 핫에 의해 상속됩니다. 생성 할 수 없습니다상속 없음이러한 유형의 제약. 상위 테이블에 동일한 제약 조건이있는 경우 이러한 유형의 제약 조건을 삭제할 수 없습니다.

  • 사용전용토토 핫이없는 한 분할 된 테이블에만 제약 조건을 추가하거나 떨어 뜨리려면 지원됩니다. 토토 핫이 존재하면 사용전용이외의 제약 조건에 대한 오류가 발생합니다.고유 한기본 키. 대신, 토토 핫 자체에 대한 제약을 추가 할 수 있고 (부모 테이블에 존재하지 않는 경우) 떨어질 수 있습니다.

  • 분할 된 테이블에 데이터 자체가 없으므로 사용 시도Truncate 전용분할 된 토토 핫에서 항상 오류를 반환합니다.

5.12.3. 상속을 사용한 분할#

내장 선언 파티셔닝은 대부분의 일반적인 사용 사례에 적합하지만보다 유연한 접근 방식이 유용한 상황이 있습니다. 파티셔닝은 테이블 상속을 사용하여 구현할 수 있으며, 이는 다음과 같은 선언 파티셔닝에서 지원하지 않는 몇 가지 기능을 허용합니다.

  • 선언적 파티셔닝의 경우, 토토 핫은 토토 핫 된 테이블과 정확히 동일한 열 세트를 가져야하는 반면 테이블 상속을 사용하면 자식 테이블이 부모에 추가 열이 없을 수 있습니다..

  • 토토 핫 상속은 여러 상속을 허용합니다.

  • 선언 파티셔닝은 범위, 목록 및 해시 분할 만 지원하는 반면, 테이블 상속은 데이터를 사용자가 선택한 방식으로 나눌 수 있습니다. (그러나 제약 제외가 하위 테이블을 효과적으로 정리할 수없는 경우 쿼리 성능이 좋지 않을 수 있습니다.)

5.12.3.1. 예#

이 예제는 위의 선언적 파티셔닝 예와 동등한 분할 구조를 구축합니다. 다음 단계를 사용하십시오.

  1. 생성루트토토 핫, 모든Child테이블이 상속됩니다. 이 테이블에는 데이터가 포함되지 않습니다. 모든 자식 테이블에 똑같이 적용되지 않는 한,이 테이블의 점검 제약 조건을 정의하지 마십시오. 인덱스 또는 고유 한 제약 조건을 정의 할 필요는 없습니다. 이 예에서는 루트 테이블이입니다.측정원래 정의 된대로 토토 핫 :

    토토 핫 측정 생성 (
        city_id int null not,
        로그 데이트 날짜는 null이 아닙니다.
        PeakTemp int,
        단위 int
    );
  2. 여러 생성Child루트 테이블에서 각각 상속되는 테이블. 일반적 으로이 테이블은 루트에서 상속 된 세트에 열을 추가하지 않습니다. 선언적 파티셔닝과 마찬가지로이 테이블은 모든면에서 정상입니다PostgreSQL토토 핫 (또는 외국 토토 핫).

    토토 핫 생성 _y2006m02 () 상속 (측정);
    테이블 측정 _y2006m03 () 상속 (측정)을 작성합니다.
    ...
    테이블 측정 _y2007m11 () 상속 (측정)을 만듭니다.
    테이블 측정 _y2007m12 () 상속 (측정)을 만듭니다.
    테이블 측정 _y2008m01 () 상속 (측정); 생성
  3. 각각의 허용 된 키 값을 정의하기 위해 자식 토토 핫에 겹치지 않는 토토 핫 제약 조건을 추가합니다.

    일반적인 예는 다음과 같습니다.

    점검 (x = 1)
    Check (County in County ( 'Oxfordshire', 'Buckinghamshire', 'Warwickshire'))))
    Check (outletid = 100 및 outletid <200)

    제약 조건이 다른 하위 테이블에서 허용되는 주요 값 사이에 중첩이 없음을 보장합니다. 일반적인 실수는 다음과 같은 범위 제약 조건을 설정하는 것입니다.

    점검 (100에서 200 사이의 outletid)
    확인 (200에서 300 사이의 outletid)

    이것은 어떤 자식 테이블이 확실하지 않기 때문에 잘못되었습니다. 대신, 범위는이 스타일로 정의되어야합니다..

    테이블 측정 생성 _y2006m02 (
        check (logdate = date '2006-02-01'및 logdate <날짜 '2006-03-01')
    ) 상속 (측정);
    
    테이블 측정 _y2006m03 생성 (
        check (logdate = date '2006-03-01'및 logdate <날짜 '2006-04-01'))
    ) 상속 (측정);
    
    ...
    테이블 측정 값 생성 _y2007m11 (
        check (logdate = date '2007-11-01'및 logdate <날짜 '2007-12-01'))
    ) 상속 (측정);
    
    테이블 측정 _y2007m12 생성 (
        check (logdate = date '2007-12-01'및 logdate <날짜 '2008-01-01')
    ) 상속 (측정);
    
    테이블 측정 _y2008m01 생성 (
        check (logdate = date '2008-01-01'및 logdate <날짜 '2008-02-01'))
    ) 상속 (측정);
  4. 각 어린이 토토 핫의 경우 키 열의 인덱스와 원하는 다른 색인을 작성하십시오..

    Measurement_Y2006M02 (logdate)에서 인덱스 측정 _y2006M02_LOGDATE 만들기;
    Measurement_Y2006M03 (logdate)에서 인덱스 측정 _y2006M03_LOGDATE를 만듭니다.
    Measurement_Y2007M11 (logdate)에서 색인 측정 _y2007m11_logdate를 만듭니다.
    Measurement_Y2007M12 (logdate)에서 색인 측정 _y2007m12_logdate를 만듭니다.
    Measurement_Y2008M01 (logdate);에서 색인 측정 _y2008m01_Logdate 작성
  5. 우리는 응용 프로그램을 말할 수 있기를 원합니다측정에 삽입 ...데이터를 해당 아동 테이블로 리디렉션하도록합니다. 적절한 트리거 함수를 루트 테이블에 연결하여이를 배열 할 수 있습니다. 데이터가 최신 자식에만 추가되면 매우 간단한 트리거 기능을 사용할 수 있습니다.

    함수 생성 또는 교체 측정 _insert_trigger ()
    트리거를 $$로 반환합니다
    시작하다
        측정 _y2008m01 값 (new.*)에 삽입;
        널 리턴;
    끝;
    $$
    언어 plpgsql;

    함수를 작성한 후 트리거 기능을 호출하는 트리거를 만듭니다.

    Trigger insert_measurement_trigger 작성
        측정에 삽입하기 전에
        각 행에 대해 execute function greatement_insert_trigger ();

    매달 트리거 함수를 재정의하여 항상 현재 하위 테이블에 삽입되도록해야합니다. 그러나 트리거 정의를 업데이트 할 필요는 없습니다.

    데이터를 삽입하고 서버가 행을 추가 해야하는 하위 테이블을 자동으로 찾을 수 있습니다. 예를 들어보다 복잡한 트리거 기능 으로이 작업을 수행 할 수 있습니다.

    함수 생성 또는 교체 측정 _insert_trigger ()
    트리거를 $$로 반환합니다
    시작하다
        if (new.logdate = date '2006-02-01'및
             new.logdate <날짜 '2006-03-01')
            측정 _y2006m02 값 (new.*)에 삽입;
        elsif (new.logdate = date '2006-03-01'및
                new.logdate <날짜 '2006-04-01')
            측정 _y2006m03 값 (new.*)에 삽입;
        ...
        elsif (new.logdate = date '2008-01-01'및
                new.logdate <날짜 '2008-02-01')
            측정 _y2008m01 값 (new.*)에 삽입;
        또 다른
            예외 '범위를 벗어난 날짜를 올리십시오.  측정 _insert_trigger () 함수! ';
        끝 IF;
        널 리턴;
    끝;
    $$
    언어 plpgsql;

    트리거 정의는 이전과 동일합니다. 각각if테스트는 정확히 일치해야합니다check아동 토토 핫의 제약 조건.

    이 함수는 단일 월 경우보다 더 복잡하지만 분기가 필요하기 전에 추가 할 수 있으므로 자주 업데이트 할 필요는 없습니다..

    Note

    실제로 대부분의 삽입물이 해당 어린이로 들어가면 최신 아동을 먼저 확인하는 것이 가장 좋습니다. 단순화를 위해이 예제의 다른 부분에서 트리거 테스트를 동일한 순서로 보여주었습니다.

    삽입물을 해당 하위 테이블로 리디렉션하는 다른 접근 방식은 루트 테이블에서 트리거 대신 규칙을 설정하는 것입니다. 예를 들어:

    규칙 생성 _insert_y2006m02 AS
    측정 값으로 삽입하십시오
        (logdate = date '2006-02-01'및 logdate <날짜 '2006-03-01'))
    대신하십시오
        측정 _y2006m02 값 (new.*)에 삽입;
    ...
    규칙 측정 _insert_y2008m01을 만듭니다
    측정 값으로 삽입하십시오
        (logdate = date '2008-01-01'및 logdate <날짜 '2008-02-01'))
    대신하십시오
        측정 _y2008m01 값 (new.*);에 삽입하십시오.

    규칙은 트리거보다 오버 헤드가 훨씬 더 많지만 오버 헤드는 행당 한 번보다 쿼리 당 한 번 지불 되므로이 방법은 벌크 삽입 상황에 유리할 수 있습니다. 그러나 대부분의 경우 트리거 방법은 더 나은 성능을 제공합니다.

    COPY규칙을 무시합니다. 사용하고 싶다면COPY데이터를 삽입하려면 루트에 직접적으로 보지 않고 올바른 자식 테이블에 복사해야합니다.COPY화재 트리거를 사용하므로 트리거 접근법을 사용하면 정상적으로 사용할 수 있습니다..

    규칙 접근법의 또 다른 단점은 규칙 세트가 삽입 날짜를 다루지 않으면 오류를 강제하는 간단한 방법이 없다는 것입니다. 데이터가 조용히 루트 테이블로 들어갑니다.

  6. 제약 _exclusion구성 매개 변수가 비활성화되지 않았습니다postgresql.conf; 그렇지 않으면 자식 토토 핫에 불필요하게 액세스 할 수 있습니다.

우리가 볼 수 있듯이 복잡한 테이블 계층은 상당한 양의 DDL을 요구할 수 있습니다. 위의 예에서는 매달 새 어린이 테이블을 만들 것이므로 필요한 DDL을 자동으로 생성하는 스크립트를 작성하는 것이 좋습니다.

5.12.3.2. 상속 파티셔닝을위한 유지 보수#

오래된 데이터를 빨리 제거하려면 더 이상 필요하지 않은 어린이 테이블을 삭제하십시오.

드롭 토토 핫 측정 _y2006m02;

상속 계층 구조 토토 핫에서 하위 토토 핫을 제거하지만 그 자체로 토토 핫로 액세스 할 수 있습니다.

ALTER 테이블 측정 _Y2006M02 상속 측정 없음;

새 데이터를 처리하기 위해 새 어린이 토토 핫을 추가하려면 오리지널 어린이가 위에서 만든 것처럼 빈 자녀 토토 핫을 만듭니다.

토토 핫 생성 _y2008m02 (
    check (logdate = date '2008-02-01'및 logdate <날짜 '2008-03-01'))
) 상속 (측정);

또는 새 어린이 토토 핫을 토토 핫 계층에 추가하기 전에 새 어린이 토토 핫을 만들고 채우고 싶을 수도 있습니다. 이를 통해 부모 토토 핫의 쿼리로 표시되기 전에 데이터를로드, 점검 및 변환 할 수 있습니다.

생성 테이블 측정 _y2008m02
  (제약 조건을 포함한 기본값을 포함한 측정과 같은);
Alter Table Measurement_Y2008M02 추가 제약 조건 Y2008M02
   check (logdate = date '2008-02-01'및 logdate <날짜 '2008-03-01');
\ '측정 _y2008m02'에서 측정 _y2008m02 복사
- 아마도 다른 데이터 준비 작업
Alter Table Measurement_Y2008M02 상속 측정;

5.12.3.3. 경고#

다음 경고는 상속을 사용하여 구현 된 분할에 적용됩니다.

  • 모든 것을 확인하는 자동 방법이 없습니다check제약은 상호 배타적입니다. 자식 테이블을 생성하고 각각을 손으로 쓰는 것보다 관련 객체를 생성 및/또는 수정하는 코드를 만드는 것이 더 안전합니다.

  • 인덱스 및 외국 주요 제약 조건은 상속 자녀가 아닌 단일 토토 핫에 적용되므로 일부가 있습니다경고

  • 여기에 표시된 체계는 행의 키 열의 값이 변하지 않거나 최소한 다른 토토 핫으로 이동하도록 요구하기에 충분히 변경되지 않는다고 가정합니다.업데이트그렇게하려고 시도하는 것은로 인해 실패 할 것입니다.check제약. 이러한 사례를 처리 해야하는 경우 자식 테이블에 적절한 업데이트 트리거를 넣을 수 있지만 구조 관리가 훨씬 더 복잡해집니다.

  • 매뉴얼진공and분석명령은 모든 상속 자식 테이블을 자동으로 처리합니다. 이것이 바람직하지 않은 경우를 사용할 수 있습니다.전용키워드. 명령 :

    측정 전용 분석;

    루트 테이블 만 처리합니다.

  • 삽입진술충돌클로스는 예상대로 작동하지 않을 것입니다.충돌행동은 아동 관계가 아니라 지정된 목표 관계에 대한 고유 한 위반의 경우에만 취해집니다.

  • 신청서가 분할 체계를 명시 적으로 알지 않는 한, 원하는 하위 토토 핫로 행을 라우팅하기 위해 트리거 또는 규칙이 필요합니다. 트리거는 쓰기가 복잡 할 수 있으며 선언적 파티셔닝을 통해 내부적으로 수행 된 튜플 라우팅보다 훨씬 느리게됩니다.

5.12.4. 토토 핫 가지 치기#

토토 핫 가지 치기는 선언적으로 분할 된 토토 핫의 성능을 향상시키는 쿼리 최적화 기술입니다. 예를 들어 :

set enable_partition_pruning = on;                 - 기본값
Logdate = Date '2008-01-01'; 측정에서 count (*)를 선택하십시오.

토토 핫 가지 치기가 없으면 위의 쿼리는의 각 토토 핫을 스캔합니다.측정테이블. 토토 핫 가지 치기가 활성화되면 플래너는 각 토토 핫의 정의를 검사하고 쿼리를 충족하는 행이 포함되어 있지 않기 때문에 토토 핫을 스캔 할 필요가 없음을 증명합니다.여기서절. 플래너가 이것을 증명할 수 있으면 (를 제외합니다.Prunes) 쿼리 계획의 토토 핫.

설명 명령과를 사용하여enable_partition_pruningconfiguration 매개 변수, 토토 핫이 다루어진 계획과 그렇지 않은 계획의 차이를 보여줄 수 있습니다. 이 유형의 테이블 설정에 대한 일반적인 최적화 된 계획은 다음과 같습니다.

set enable_partition_pruning = off;
로그 데이트 = 날짜 '2008-01-01'에서 측정에서 선택한 수 (*)를 설명하십시오.
                                    쿼리 계획
---------------------------------------------------------------------------------------
 집계 (비용 = 188.76..188.77 행 = 1 너비 = 8)
   - Append (비용 = 0.00..181.05 행 = 3085 너비 = 0)
         - 측정 _y2006m02에서 SEQ 스캔 (비용 = 0.00..33.12 행 = 617 너비 = 0)
               필터 : (logdate = '2008-01-01':: 날짜)
         - 측정 _y2006m03의 SEQ 스캔 (비용 = 0.00..33.12 행 = 617 너비 = 0)
               필터 : (logdate = '2008-01-01':: 날짜)
...
         - 측정 _y2007m11의 SEQ 스캔 (비용 = 0.00..33.12 행 = 617 너비 = 0)
               필터 : (logdate = '2008-01-01':: 날짜)
         - 측정 _y2007m12에서 SEQ 스캔 (비용 = 0.00..33.12 행 = 617 너비 = 0)
               필터 : (logdate = '2008-01-01':: 날짜)
         - 측정 _y2008m01에서 SEQ 스캔 (비용 = 0.00..33.12 행 = 617 너비 = 0)
               필터 : (logdate = '2008-01-01':: 날짜)

토토 핫의 일부 또는 모든 토토 핫은 전체 테이블 순차 스캔 대신 인덱스 스캔을 사용할 수 있지만 여기서는이 쿼리에 응답하기 위해 이전 토토 핫을 전혀 스캔 할 필요가 없다는 것입니다. 토토 핫 가지 치기를 활성화하면 동일한 답변을 전달할 상당히 저렴한 계획을 얻습니다.

set enable_partition_pruning = on;
로그 데이트 = 날짜 '2008-01-01'에서 측정에서 선택한 수 (*)를 설명하십시오.
                                    쿼리 계획
---------------------------------------------------------------------------------------
 집계 (비용 = 37.75..37.76 행 = 1 너비 = 8)
   - 측정 _y2008m01에서 SEQ 스캔 (비용 = 0.00..33.12 행 = 617 너비 = 0)
         필터 : (logdate = '2008-01-01':: 날짜)

토토 핫 가지 치기는 인덱스의 존재가 아니라 토토 핫 키에 의해 암시 적으로 정의 된 제약 조건에 의해서만 구동됩니다. 따라서 키 열의 인덱스를 정의 할 필요는 없습니다. 주어진 토토 핫에 대해 인덱스를 만들어야하는지 여부는 토토 핫을 스캔하는 쿼리가 일반적으로 토토 핫의 많은 부분을 스캔 할 것이라고 기대하는지 여부에 따라 다릅니다. 색인은 후자의 경우에 도움이되지만 전자는 아닙니다.

토토 핫 치기는 주어진 쿼리의 계획 중뿐만 아니라 실행 중에도 수행 할 수 있습니다. 이것은 조항이 쿼리 계획 시간에 값을 알 수없는 표현식 (예 : a에 정의 된 매개 변수)을 포함 할 때 더 많은 토토 핫을 가지 치기를 허용 할 수 있으므로 유용합니다.준비stubquery에서 얻은 값을 사용하거나 중첩 루프 조인의 내부에서 매개 변수화 된 값을 사용합니다. 실행 중 토토 핫 가지 치기는 다음 시간 중 하나에 수행 할 수 있습니다.

  • 쿼리 계획의 초기화 중. 실행 초기화 단계에서 알려진 매개 변수 값에 대해 토토 핫 가지 치기를 수행 할 수 있습니다. 이 단계에서 가지 치기 된 토토 핫은 쿼리에 표시되지 않습니다설명또는분석. 이 단계에서 제거 된 토토 핫 수를 결정할 수 있습니다.하위 계획 제거설명출력. 쿼리 플래너는 계획의 일부인 모든 토토 핫에 대한 잠금 장치를 얻습니다. 그러나 집행자가 캐시 된 계획을 사용하는 경우, 실행 초기화 단계에서 수행 된 토토 핫 가지 치기 이후에 남아있는 토토 핫에서만 잠금을 얻습니다.설명출력이 아니라하위 계획 제거속성.

  • 쿼리 계획의 실제 실행 중. 토토 핫 가지 치기는 또한 실제 쿼리 실행 중에 만 알려진 값을 사용하여 토토 핫을 제거하기 위해 여기에서 수행 될 수 있습니다. 여기에는 하위 쿼리의 값과 매개 변수화 된 중첩 루프 조인의 것과 같은 실행 시간 매개 변수의 값이 포함됩니다. 쿼리 실행 중에 이러한 매개 변수의 값이 여러 번 변경 될 수 있으므로, 토토 핫 가지 치기 변경에 의해 사용되는 실행 매개 변수 중 하나가있을 때마다 토토 핫 가지 치기가 수행됩니다. 이 단계에서 토토 핫을 가지 치기를 결정하려면 신중한 검사가 필요합니다루프분석출력. 상이한 토토 핫에 해당하는 하위 계획은 실행 중에 각각 정리 된 횟수에 따라 다른 값을 가질 수 있습니다. 일부는로 표시 될 수 있습니다.(절대 실행)그들이 매번 가지 치기를 한 경우.

토토 핫 가지 치기는를 사용하여 비활성화 할 수 있습니다enable_partition_pruning설정.

5.12.5. 분할 및 제약 제외#

제약 제외는 토토 핫 가지 치기와 유사한 쿼리 최적화 기술입니다. 레거시 상속 방법을 사용하여 구현 된 분할에 주로 사용되지만 선언적 파티셔닝을 포함하여 다른 목적으로 사용할 수 있습니다.

제약 제외는 각 테이블을 사용한다는 점을 제외하고는 토토 핫 가지 치기와 매우 유사한 방식으로 작동합니다.check이름을 부여하는 제약 조건 - 토토 핫 치기는 선언적 파티셔닝의 경우에만 존재하는 테이블의 토토 핫 경계를 사용합니다. 또 다른 차이점은 제약 제외가 계획 시간에만 적용된다는 것입니다. 실행 시간에 토토 핫을 제거하려는 시도가 없습니다.

제약 제외가 사용한다는 사실check토토 핫 가지 치기와 비교하여 느리게하는 제약 조건은 때때로 이점으로 사용할 수 있습니다. 내부 토토 핫 경계 외에도 선언적으로 분류 된 테이블에서도 제약 조건을 정의 할 수 있기 때문에 제약 제한 배제는 쿼리 계획에서 추가 토토 핫을 제거 할 수 있습니다.

기본 (및 권장) 설정제약 _exclusiononNOROFF이지만 중간 설정토토 핫,이 기술은 상속 파티 파티 토토 핫에서 작동 할 수있는 쿼리에만 적용됩니다. 그만큼on설정 설정 플래너가 검사하게됩니다check모든 쿼리의 제약 조건, 혜택이없는 간단한 쿼리조차도

다음 경고는 제약 제외에 적용됩니다 :

  • 제약 제외는 토토 핫 가지 치기와 달리 쿼리 계획 중에 만 적용됩니다. 쿼리 실행 중에도 적용 할 수 있습니다.

  • 제약 제외는 쿼리의 경우에만 작동합니다여기서절은 상수 (또는 외부로 제공된 매개 변수)를 포함합니다. 예를 들어,와 같은 상상할 수없는 함수에 대한 비교current_timestamp플래너가 어떤 자식 토토 핫을 알 수 없으므로 최적화 할 수 없습니다.

  • 분할 제약 조건을 간단하게 유지하십시오. 그렇지 않으면 플래너는 자식 테이블을 방문 할 필요가 없음을 증명하지 못할 수 있습니다. 목록 분할에 간단한 평등 조건을 사용하거나 앞의 예제와 같이 범위 분할을위한 간단한 범위 테스트를 사용하십시오. 좋은 규칙은 토토 핫 제약 조건에 B- 트리-무인 연산자를 사용하여 토토 핫 열을 상수와 비교하는 것만 포함되어야한다는 것입니다.

  • 부모 테이블의 모든 어린이에 대한 모든 제약은 제약 제외 중에 검사되므로 많은 어린이들이 쿼리 계획 시간을 상당히 증가시킬 가능성이 높습니다. 따라서 레거시 상속 기반 파티셔닝은 아마도 100 개의 어린이 테이블과 잘 어울릴 것입니다. 수천 명의 아이들을 사용하려고하지 마십시오.

5.12.6. 선언 파티셔닝을위한 모범 사례#

쿼리 계획 및 실행의 성능이 열악한 설계에 의해 부정적인 영향을받을 수 있으므로 토토 핫을 분할하는 방법의 선택을 신중하게 만들어야합니다..

가장 중요한 설계 결정 중 하나는 데이터를 분할하는 열 또는 열입니다. 종종 최선의 선택은 가장 일반적으로 나타나는 열이나 열 세트로 분할하는 것입니다.어디분할 된 토토 핫에서 실행되는 쿼리의 조항.어디토토 핫 경계 제약과 호환되는 조항을 사용하여 불필요한 토토 핫을 가두는 데 사용할 수 있습니다. 그러나, 당신은에 대한 요구 사항에 따라 다른 결정을 내릴 수 있습니다.기본 키또는 A고유 한제약. 원치 않는 데이터를 제거하는 것도 토토 핫 전략을 계획 할 때 고려해야 할 요소입니다. 전체 토토 핫은 상당히 빠르게 분리 될 수 있으므로 한 번에 제거 할 모든 데이터를 단일 토토 핫에 위치시키는 방식으로 토토 핫 전략을 설계하는 것이 좋습니다..

테이블을 나누어야 할 대상 토토 핫 수를 선택하는 것도 중요한 결정입니다. 분할이 충분하지 않으면 인덱스가 너무 커지고 데이터 로컬 성이 나빠져 캐시 적중률이 낮아질 수 있습니다. 그러나 테이블을 너무 많은 토토 핫으로 나누면 문제가 발생할 수 있습니다. 너무 많은 토토 핫은 아래에 설명 된 것처럼 쿼리 계획 및 실행 중에 더 긴 쿼리 계획 시간과 메모리 소비가 더 높은 것을 의미 할 수 있습니다. 테이블을 분할하는 방법을 선택할 때 미래에 어떤 변화가 발생할 수 있는지 고려하는 것도 중요합니다. 예를 들어, 고객 당 토토 핫을 선택하고 현재 소수의 대규모 고객이있는 경우 몇 년 안에 많은 소규모 고객과 함께 자신을 찾으면 그 의미를 고려하십시오. 이 경우의 토토 핫을 선택하는 것이 좋습니다.HASH|목록그리고 고객의 수가 데이터를 분할하는 것이 실용적인 것 이상으로 증가하지 않기를 희망합니다.

하위 토토 핫은 다른 토토 핫보다 더 커질 것으로 예상되는 토토 핫을 추가로 나눌 수 있습니다. 또 다른 옵션은 토토 핫 키에 여러 열이있는 범위 파티셔닝을 사용하는 것입니다. 이 중 하나는 쉽게 과도한 수의 토토 핫으로 이어질 수 있으므로 구속이 권장됩니다.

쿼리 계획 및 실행 중에 분할의 오버 헤드를 고려하는 것이 중요합니다. 쿼리 플래너는 일반적으로 쿼리 플래너가 소수의 토토 핫을 제외한 모든 토토 핫을 제외한 모든 쿼리를 위해 최대 수천 개의 토토 핫이 상당히 잘 토토 핫 계층을 처리 할 수 있습니다. 플래너가 토토 핫 가지 치기를 수행 한 후 더 많은 토토 핫이 남아있을 때 계획 시간이 길어지고 메모리 소비가 더 높아집니다. 다수의 토토 핫을 갖는 것에 대해 우려하는 또 다른 이유는 서버의 메모리 소비가 시간이 지남에 따라, 특히 많은 세션이 많은 토토 핫에 닿는 경우 크게 증가 할 수 있기 때문입니다. 각 토토 핫은 메타 데이터를 각 세션의 로컬 메모리에로드해야하기 때문입니다.

데이터웨어 하우스 유형 워크로드를 사용하면보다 더 많은 토토 핫을 사용하는 것이 합리적 일 수 있습니다OLTP워크로드를 입력하십시오. 일반적으로 데이터웨어 하우스에서 쿼리 계획 시간은 쿼리 실행 중에 대부분의 처리 시간이 소비되므로 쿼리 계획 시간은 문제가되지 않습니다. 이 두 가지 유형의 워크로드 중 하나를 사용하면 대량의 데이터를 재조정하는 것이 고통스럽게 느려질 수 있으므로 올바른 결정을 조기에 내리는 것이 중요합니다. 의도 된 워크로드의 시뮬레이션은 종종 토토 핫 전략을 최적화하는 데 유리합니다. 더 많은 토토 핫이 더 적은 토토 핫보다 낫거나 그 반대도 마찬가지라고 가정하지 마십시오.