PostgreSQLSQL 고유성 제약 조건을 사용하여고유 토토 결과, 동일한 키로 여러 항목을 허용하지 않는 색인입니다. 이 기능 세트를 지원하는 액세스 방법Amcanunique
true. (현재 B-Tree 만 지원합니다.) 열에 나열된 열포함
고유성을 시행 할 때 조항을 고려하지 않습니다.
MVCC 때문에 항상 인덱스에 중복 항목이 존재하도록해야합니다. 항목은 단일 논리 행의 연속 버전을 참조 할 수 있습니다. 우리가 실제로 시행하고 싶은 동작은 MVCC 스냅 샷에 동일한 인덱스 키를 가진 두 개의 행이 포함될 수 없다는 것입니다. 새 행을 고유 한 색인에 삽입 할 때 확인 해야하는 다음 사례로 분류됩니다.
현재 트랜잭션으로 충돌하는 유효한 행이 삭제 된 경우 괜찮습니다. (특히 업데이트는 새 버전을 삽입하기 전에 항상 이전 행 버전을 삭제하므로 키를 변경하지 않고 행에 업데이트 할 수 있습니다.)
충돌 행이 그 대신에 커밋 된 트랜잭션에 의해 삽입 된 경우, 삽입자는 해당 트랜잭션이 유발되는지 확인해야합니다. 그것이 롤백되면 갈등이 없습니다. 충돌하는 행을 다시 삭제하지 않고 커밋되면 독창성 위반이 있습니다. (실제로 우리는 다른 거래가 종료 될 때까지 기다린 다음 가시성 점검을 다시 시작합니다.)
마찬가지로, 유효한 행이 충돌하는 유효한 행이 그 대신 커미션 된 트랜잭션에 의해 삭제 된 경우, 삽입자는 해당 트랜잭션이 커밋 또는 중단되기를 기다린 다음 테스트를 반복해야합니다..
또한, 위의 규칙에 따라 독창성 위반을보고하기 직전에 액세스 방법은 삽입되는 행의 활기를 다시 확인해야합니다. 그것이 사망 한 경우 위반은보고되어야합니다. (이 경우는 현재 트랜잭션에서 방금 생성 된 행을 삽입하는 일반적인 시나리오에서 발생할 수 없습니다.동시에 고유 한 색인 생성
, 그러나)
우리는이 테스트 자체를 적용하기 위해 토토 결과 액세스 방법이 필요합니다. 즉, 토토 결과 내용에 따라 중복 키가있는 것으로 표시되는 모든 행의 커밋 상태를 확인하기 위해 힙에 도달해야합니다. 이것은 의심 할 여지없이 추악하고 비 모드형이지만 중복 작업을 저장합니다. 별도의 프로브를 수행하면 충돌 행에 대한 토토 결과 조회가 새로운 행의 토토 결과 항목을 삽입 할 장소를 찾는 동안 본질적으로 반복됩니다. 또한 충돌 점검이 새로운 토토 결과 항목의 삽입의 필수 요소가 아니라면 레이스 조건을 피할 수있는 명백한 방법은 없습니다.
고유 한 제약 조건을 연기 할 수있는 경우 추가 복잡성이 있습니다. 새 행에 대한 토토 결과 항목을 삽입 할 수 있어야하지만 명령문이 끝날 때까지 또는 나중에 독창성 폭력 오류를 연기해야합니다. 토토 결과의 불필요한 반복 검색을 피하기 위해 토토 결과 액세스 방법은 초기 삽입 중에 예비 고유성 검사를 수행해야합니다. 이것이 분명히 상충되는 라이브 튜플이 없다는 것을 보여 주면, 우리는 끝났습니다. 그렇지 않으면, 우리는 제약 조건을 시행 할 때가되도록 재확인을 예약합니다. 재확인 시점에서 삽입 된 튜플과 동일한 키를 가진 다른 튜플이 모두 실시되면 오류를보고해야합니다. (이 목적을 위해“라이브”실제로 의미“인덱스 항목의 핫 체인의 튜플은 라이브입니다”.) 이것을 구현하려면Aminsert
함수가 전달 됨Checkunique
다음 값 중 하나가있는 매개 변수 :
고유 _check_no
고유성 점검을 수행해서는 안된다는 것을 나타냅니다 (이것은 고유 한 색인이 아닙니다).
고유 한 _check_yes
| 이것은 이는 고유 한 고유 한 지수임을 나타냅니다. 고유성 점검은 위에서 설명한대로 즉시 수행해야합니다..
고유 한 _check_partial
고유 한 제약이 연기 가능하다는 것을 나타냅니다.PostgreSQL이 모드를 사용하여 각 행의 토토 결과 항목을 삽입합니다. 액세스 방법은 토토 결과에 중복 항목을 허용해야하며에서 false를 반환하여 잠재적 복제물을보고해야합니다.Aminsert
. False가 반환되는 각 행에 대해, 지연된 재확인이 예정됩니다.
액세스 방법은 고유 한 제약 조건을 위반할 수있는 행을 식별해야하지만 허위 긍정을보고하는 것은 오류가 아닙니다. 이를 통해 다른 거래가 완료되기를 기다리지 않고 수표를 수행 할 수 있습니다. 여기에보고 된 갈등은 오류로 취급되지 않으며 나중에 다시 확인 될 것이며,이 시간은 더 이상 갈등이되지 않을 수 있습니다.
고유 _check_existing
이것은 잠재적 인 독창성 위반으로보고 된 행을 연기 한 재발임을 나타냅니다. 이것은 전화로 구현되지만Aminsert
, 액세스 방법은아님이 경우 새 인덱스 항목을 삽입하십시오. 인덱스 항목이 이미 있습니다. 오히려 액세스 방법은 다른 라이브 인덱스 항목이 있는지 확인해야합니다. 그렇다면 대상 행이 여전히 남아 있으면 오류를보고합니다.
A에서 권장됩니다고유 한 _check_existing
호출, 액세스 방법은 대상 행에 실제로 인덱스에 기존 항목이 있는지 확인하고 그렇지 않은 경우 오류를보고합니다. 인덱스 튜플 값이 전달 되었기 때문에 이것은 좋은 생각입니다.Aminsert
다시 계산되었습니다. 색인 정의에 실제로 불변이 아닌 함수가 포함되면 인덱스의 잘못된 영역을 확인할 수 있습니다. 대상 행이 다시 확인되는지 확인하면 원래 삽입에 사용 된 것과 동일한 튜플 값을 스캔하고 있는지 확인합니다.