당신이 디자인 한 것이 좋습니다. 추가해야 할 것은 관계를 무 방향으로 만드는 제약입니다. 따라서 행을 추가 (1,5)
하지 않으면 행을 가질 수 없습니다 (5,1)
.
이 수행 할 수 있습니다 * 다리 테이블에 자기 참조 제약과 함께.
* : Postgres, Oracle, DB2 및 SQL 표준에 설명 된대로 외래 키 제약 조건을 구현 한 모든 DBMS에서 수행 할 수 있습니다 (예 : 트랜잭션이 끝날 때 확인 됨). 진술의 끝에 그들을 확인하는 서버 와이 구성은 여전히 작동합니다. 당신은 MySQL의에서이 작업을 수행 할 수 있기 때문에 "이노 검사 UNIQUE 및 FOREIGN KEY 제약 행 단위" .
따라서 Postgres에서 다음은 요구 사항과 일치합니다.
CREATE TABLE x
(
x_id SERIAL NOT NULL PRIMARY KEY,
data VARCHAR(10) NOT NULL
);
CREATE TABLE bridge_x
(
x_id1 INTEGER NOT NULL REFERENCES x (x_id),
x_id2 INTEGER NOT NULL REFERENCES x (x_id),
PRIMARY KEY(x_id1, x_id2),
CONSTRAINT x_x_directionless
FOREIGN KEY (x_id2, x_id1)
REFERENCES bridge_x (x_id1, x_id2)
);
테스트 대상 : SQL-Fiddle
행을 추가하려고하면 (1,5)
:
INSERT INTO bridge_x VALUES
(1,5) ;
다음과 같이 실패합니다.
오류 : "bridge_x"테이블의 삽입 또는 업데이트가 외래 키 제약 조건 "x_x_directionless"를 위반합니다
. 세부 정보 : Key (x_id2, x_id1) = (5, 1)이 "bridge_x"테이블에 없습니다. :
INSERT INTO bridge_x VALUES (1,5)
또한 행 CHECK
을 금지하려는 경우 제약 조건을 추가 할 수 있습니다 (y,y)
.
ALTER TABLE bridge_x
ADD CONSTRAINT x_x_self_referencing_items_not_allowed
CHECK (x_id1 <> x_id2) ;
언급 한대로 열에 하위 ID를 입력 x_id1
하고 상위 ID를 강제로 지정하여 관계의 한 방향 (한 행에 두 개가 아닌)을 저장하는 것과 같이 이것을 구현하는 다른 방법이 있습니다 x_id2
. 구현하기가 더 쉬워 보이지만 나중에는 더 복잡한 쿼리가 발생합니다.
CREATE TABLE bridge_x
(
x_id1 INTEGER NOT NULL REFERENCES x (x_id),
x_id2 INTEGER NOT NULL REFERENCES x (x_id),
PRIMARY KEY(x_id1, x_id2),
CONSTRAINT x_x_directionless
CHECK (x_id1 <= x_id2) -- or "<" to forbid `(y,y)` rows
);