2009-07-27 4 views
0

기본 키가 a_id이고 외래 키가 b_id 인 테이블이 있다고 가정 해보십시오.기본 키와 외래 키가 절대로 교차하지 않도록하는 가장 좋은 방법은 무엇입니까?

a_idb_id이 절대 교차하지 않는 것이 중요합니다. 즉, a_id = b_id이 존재하지 않아야합니다.

이것을 구현하는 가장 좋은 방법은 무엇입니까? 어떻게 든 데이터베이스 끝 (mySql)에서이 작업을 수행 할 수 있습니까? 아니면 프로그래밍 방식으로이 작업을 수행해야합니까? 이 방식을 프로그래밍 방식으로 보장한다면 기본 키에 숫자를 삽입하는 것이 좋지 않은가? (데이터베이스에 자동 증가시키지 말고)? 난 그냥 최신 기본 키를 확인하고 단순히 그것을 증분하는 루틴을 만들 것이라고 가정하고 a_id의 범위가 결코 b_id의 범위를 교차하지 않도록해야합니다. 어떤 제안?

+0

일반적으로 외래 키는 해당 기본 키와 일치해야합니다. A와 B의 교집합은 B와 같아야합니다 (단, B에 일치하는 항목이없는 A의 항목이있을 수도 있음). 그렇다면 기본 키와 외래 키가 교차하지 않는다는 것은 무엇을 의미합니까? 왜? –

답변

2

자동 증가 필드가있는 다른 테이블을 만들 수 있습니다. 레코드를 삽입하면 "키 테이블"에 삽입되어 참조 된 값을 사용합니다. 따라서 하나의 테이블에 두 개의 전역 적으로 고유 한 키가있는 경우 각 삽입은 두 개의 키 삽입이됩니다. 이 솔루션은 2 이상으로 확장됩니다.

하지만 물어볼 필요가 있습니다. 왜?

+0

기본적으로 각 키는 결국 페이지에 표시되는 일반 객체 ID를 나타냅니다. 나는 javascript 식별자가 일반적으로 객체 id (a_id와 b_id가 교차하는 경우에는 작동하지 않음)로 항목을 식별하기를 원했습니다. 너무 많은 번거 로움이있을 경우 프론트 엔드에서 재 설계 할 수 있습니다. db 측 – oym

+0

두 번째 고유 한 열 대신 Object_Type과 같은 다른 열을 사용하는 것이 좋습니다. 또한 GUID를 생성하여 사용할 수도 있습니다. – tsilb

+0

가장 간단한 해결책은 "마스터 테이블"접근법을 사용하고 다른 삽입 전에이 테이블에 삽입하고 자동 증가 ID를 빌려 오는 것입니다. 팁 주셔서 감사합니다 – oym

1

오라클에서는 두 테이블의 행에 ID를 할당하는 데 사용 된 sequence을 사용하여이 동작을 구현할 수 있습니다. 각 테이블은 INSERT에 트리거를 가지며 여기서 id는 시퀀스의 다음 번호에서 설정됩니다.

1

한 테이블에 홀수가 있고 다른 테이블에는 단지가되도록 AUTO_INCREMENT 값을 설정할 수 있습니다.

이것은 매우 효과적 일 수 있지만, 또 다른 고유 키가있는 세 번째 테이블을 추가 할 여지는 없습니다.

나는 MySQL에 대해 100 % 확신하지는 않지만 오라클을 사용하면 시퀀스를 정의 할 수있다. 그런 다음 동일한 시퀀스를 사용하여 모든 값을 선택하는 것이 가장 좋은 옵션이다 (mysql).

+0

'b_id'가 부모 ID이고'a_id'를 수퍼 세트로 참조한다면 이것은 작동하지 않을 것입니다. – Eric

+0

어쩌면 질문을 잘못 읽었을 지 모르지만 b_id가 a_id의 하위 집합이되기를 바란다는 것을 알지 못했습니다. 그렇다면 올바른 것입니다. 그러나 일부 다른 답변에서 제안 된 것처럼 시퀀스를 사용하는 경우에도 이와 동일한 결함이 존재합니다. –

0

가장 쉬운 방법은 CHECK 제약 조건을 사용하는 것입니다. 유감스럽게도 MySQL은 MySQL이기 때문에 CHECK을 지원하지 않습니다.

MySQL에서 동일한 효과를 얻으려면 두 값이 모두 유효한지 확인하기 위해 BEFORE INSERTBEFORE UPDATE 트리거를 만들어야합니다. FK는 관계가 유효한지 확인하는 일을 담당합니다. 다음은 예입니다

CREATE TRIGGER upd_check BEFORE UPDATE ON sometable 
FOR EACH ROW 
BEGIN 
    IF NEW.a_id = NEW.b_id THEN 
     call ERROR_SELFREFERENCING_ID(); 
    END IF; 
END; 
MySQL의 트리거에 대한

상세 정보는 MySQL 매뉴얼에 사용할 수 있습니다

18.3.1: Trigger Syntax

이 편집 : MySQL은 현재 RAISE 또는 SIGNAL을 지원하지 않습니다 그들의 트리거에서, 그래서 나는 그것을 존재하지 않는 프로 시저 ERROR_SELFREFERENCING_ID() 호출에 의존해야합니다. 이로 인해 a_id = b_id 인 경우 INSERT 또는 UPDATE이 실패하게됩니다. 이는 잘못된 값인 b_id을 설정하는 것과 거의 같습니다.

0

GUID (UUID)을 고유 키로 사용할 수 있습니다.

저는 이것을 여러 프로젝트에서 사용했으며 인덱스 성능에 적합하지는 않지만 고유성을 위해 잘 작동합니다.

관련 문제