지연 불가 대 초기 즉시 지연 가능
Database Systems-The Complete BookDEFERRABLE
에서 SQL 키워드 에 대해 읽었습니다 .
후자의 [NOT DEFERRABLE] 이 기본값이며 데이터베이스 수정 명령문이 실행될 때마다 수정이 외래 키 제약 조건을 위반할 수있는 경우 제약 조건이 즉시 확인됩니다.
그러나 제약 조건을 DEFERRABLE로 선언하면 제약 조건을 확인하기 전에 트랜잭션이 완료 될 때까지 기다리는 옵션이 있습니다.
INITIALLY DEFERRED 또는 INITIALLY IMMEDIATE에 의해 DEFERRABLE 키워드를 따릅니다 . 전자의 경우 각 트랜잭션이 커밋되기 직전에 검사가 연기됩니다. 후자의 경우 각 진술 직후에 확인이 이루어집니다.
와 어떻게 NOT DEFERRABLE
다른 DEFERRABLE INITIALLY IMMEDIATE
가요? 두 경우 모두 각 개별 문 후에 제약 조건이 확인되는 것 같습니다.
으로 DEFERRABLE INITIALLY IMMEDIATE
당신이 그것을 필요로 할 때 필요에 따라 제약 조건을 지연시킬 수 있습니다.
일반적으로 명령문 시간에 제약 조건을 확인하려는 경우 유용하지만, 예를 들어 일괄로드가 커밋 시간까지 확인을 연기하려는 경우에 유용합니다.
그러나 제약 조건을 연기하는 방법은 다양한 DBMS에 따라 다릅니다.
함께 NOT DEFERRABLE
혹시 시간이 커밋 될 때까지 검사를 연기 할 수 없을 것입니다.
다른 (정확한) 답변 외에도 PostgreSQL에 대해 말할 때 다음과 같이 명시해야합니다.
와 NOT DEFERRABLE 각 행은 삽입 / 업데이트시 체크
와 DEFERRABLE (현재 IMMEDIATE ) 모든 행은 삽입 / 업데이트의 마지막에 체크
와 DEFERRABLE (현재 DEFERRED ) 모든 행이 트랜잭션의 끝에서 확인됩니다
따라서 DEFERRABLE 제약 조건이 IMMEDIATE로 설정 될 때 NOT DEFERRABLE 제약 조건처럼 작동한다고 말하는 것은 올바르지 않습니다.
이 차이점에 대해 자세히 설명하겠습니다.
CREATE TABLE example(
row integer NOT NULL,
col integer NOT NULL,
UNIQUE (row, col) DEFERRABLE INITIALLY IMMEDIATE
);
INSERT INTO example (row, col) VALUES (1,1),(2,2),(3,3);
UPDATE example SET row = row + 1, col = col + 1;
SELECT * FROM example;
이것은 올바르게 출력합니다.
그러나 DEFERRABLE INITIALLY IMMEDIATE 명령을 제거하면
오류 : 중복 키 값이 "example_row_col_key"고유 제약 조건을 위반합니다. DETAIL : 키 ( "row", col) = (2, 2)가 이미 있습니다. ********** 오류 **********
오류 : 중복 키 값이 고유 제약 조건 "example_row_col_key"를 위반했습니다. SQL 상태 : 23505 세부 정보 : 키 ( "row", col) = (2, 2)가 이미 있습니다.
부록 (2017 년 10 월 12 일)
이 동작은 실제로 여기 "호환성"섹션에 설명되어 있습니다 .
또한 PostgreSQL은 표준이 제안하는 것처럼 명령문의 끝이 아니라 지연 불가능한 고유성 제약 조건을 즉시 확인합니다.
연기 할 수 있다는 것이 명백한 것 외에도 차이점은 실제로 성능입니다. 성능 저하가 없다면 지연 가능 여부를 선택할 수있는 옵션이 필요하지 않을 것입니다. 모든 제약은 단순히 지연 가능할 것입니다.
성능 불이익은 데이터가 제한되는 방식에 대한 지식이 주어지면 데이터베이스가 수행 할 수있는 최적화와 관련이 있습니다. 예를 들어, Oracle에서 고유 한 제약 조건을 지원하기 위해 생성 된 인덱스는 일시적으로 중복을 허용해야하기 때문에 제약 조건이 연기 가능한 경우 고유 인덱스가 될 수 없습니다. 그러나 제약 조건이 지연 가능하지 않으면 인덱스가 고유 할 수 있습니다.
NOT DEFERRABLE-제약 조건 검사를 변경할 수 없습니다. 오라클은 각 문 다음에 (즉, 삽입 문 바로 뒤에)이를 확인합니다.
DEFERRABLE INITIALLY IMMEDIATE - oracle checks constraint after each statement. BUT, you can change it to after each transaction(i.e. after commit):
set constraint pk_tab1 deferred;
I'm very late to the party but I wanted to add that -- as of December 2018 -- only two databases I know of (there may be more) offer some level of implementation of this standard SQL feature:
Database NOT DEFERRABLE DEFERRABLE DEFERRABLE
INITIALLY IMMEDIATE INITIALLY DEFERRED
---------- -------------- ------------------- ------------------
Oracle N/A *1 Yes (default) Yes
PostgreSQL Yes (default) Yes Yes
DB2 - - -
SQL Server - - -
MySQL - - -
MariaDB - - -
SAP Sybase - - -
HyperSQL - - -
H2 - - -
Derby - - -
*1 Even though Oracle 12c accepts the NOT DEFERRABLE
constraint state, it actually ignores it and makes it work as DEFERRABLE INITIALLY IMMEDIATE
.
As you see, Oracle does not implement the first type (NOT DEFERRABLE
), and that's why developers using Oracle (the OP in this case) may get confused and consider the first two types equivalent.
Interestingly enough Oracle and PostgreSQL have a different default type. Maybe it has performance implications.
참고 URL : https://stackoverflow.com/questions/5300307/not-deferrable-versus-deferrable-initially-immediate
'Programing' 카테고리의 다른 글
내 div 여백이 겹치는 이유는 무엇이며 어떻게 수정할 수 있습니까? (0) | 2020.10.17 |
---|---|
onActivityResult () 전에 onResume ()이 호출됩니까? (0) | 2020.10.17 |
MATLAB에서 동일한 파일에 스크립트와 함수 정의가있을 수 있습니까? (0) | 2020.10.17 |
현재 클립 보드 콘텐츠를 받으시겠습니까? (0) | 2020.10.17 |
MySQL에서 삼항 조건 연산자를 구현하는 방법 (0) | 2020.10.16 |