2009-09-20 6 views
1

알았어 애플리케이션 레이어에서이 작업을 수행 할 수 있다는 것을 알고 있습니다.이 작업은 아마도 가장 쉬운 작업이지만, DB에 오류가 발생하지 않도록 할 수 있습니다. 진지한 질문여러 열에 걸쳐 양방향 고유 인덱스를 구현하는 방법

두 개의 열 X와 Y가 있습니다. 각 열에 두 개의 정수 (A 또는 B 중 하나의 열)를 저장합니다. 그것이 가능한 것은 어떤 경우에 우리는 B와 A와 열 Y로

  1. 열 X가 있어야 같은 것을 고유 인덱스 제약 조건을 가지고
와 B 및 열 Y와
  • 열 X

    나는 시나리오를 줄 것이다

    나는 두 명의 사용자가 있는데, userA는 id 678498이고 userB는 id 679879이다. 두 사용자는이 세션에 대한 새로운 레코드를 테이블에 저장해야한다는 2 인 게임을하려고한다. (tbl_chalenger). 이렇게하려면 열이 "host"및 "challenger"인 테이블이 있습니다.

    나는 고유의 구속이

    UNIQUE KEY `UNIQUE_PARTICIPANTS` (`host`,`challenger`) 
    

    브랜딩 사용자로 tbl_challenger에 호스트를 추가하거나 도전자가 게임을 시작한 사람에 기본적으로 달려있다. 사용자 A가 게임을 시작 그래서 경우 동시에 사용자 B가 사용자 A와 함께 게임을 시작하려고하면, 슬프게도하지만 새 레코드를 생성

    INSERT INTO `tbl_challenger` VALUES(678498 , 679879); 
    

    을 다음과 같이 우리가 쿼리를 가지고, 우리는

    INSERT INTO `tbl_challenger` VALUES(679879, 678498); 
    
    를 얻을 수

    같은 참여자의 새로운 불필요한 행을 만듭니다. 이것은 UNIQUE 키 제약에 관계없이.

    그래서 내 질문은 "호스트 도전자"뿐만 아니라 "는 도전자 호스트는"MySQL의에서 내가 할 수있는 유일한 방법은 동일한 데이터 쌍

  • 답변

    8

    을 가질 수 있도록? 양방향 제약 조건을 가지고하는 방법입니다

    CREATE TRIGGER uinsert BEFORE INSERT ON tbl_challenger 
    FOR EACH ROW SET NEW.u0 = LEAST(NEW.host,NEW.challenger), 
        NEW.u1 = GREATEST(NEW.host,NEW.challenger); 
    CREATE TRIGGER uupdate BEFORE UPDATE ON tbl_challenger 
    FOR EACH ROW SET NEW.u0 = LEAST(NEW.host,NEW.challenger), 
        NEW.u1 = GREATEST(NEW.host,NEW.challenger); 
    
    : 생각의

    CREATE TABLE tbl_challenger (
        host int, 
        challenger int, 
        u0 int, u1 int 
    ); 
    

    같은 유틸리티 열 몇 가지를 추가하고 u0과 적어도에 u1 두의 큰 설정 트리거의 몇 가지를 추가하는 것입니다

    는 당신은 (u0,u1)

    CREATE UNIQUE INDEX uniqueness ON tbl_challenger(u0,u1); 
    

    에 고유 인덱스를 추가 그리고 지금 당신은 순서에 관계없이 중복 쌍을 삽입하려고 오류가 발생합니다. PostgreSQL 같은 괜찮은 RDBMS에

    당신이 표현에 인덱스를 사용할 수있을 것입니다 :

    CREATE UNIQUE INDEX uniqueness ON tbl_challenger 
        (LEAST(host,challenger), GREATEST(host,challenger)); 
    

    그래서, 그 전에 스위치가 ;-)

    +0

    나는 지금 이것을 시도하고 몇 분 후에보고 할 것입니다! – stone

    +0

    물론, 시간이 걸릴 ;-) –

    +0

    우수 작품 완벽하게! 예, 단지 MySQL을 사용하는 응용 프로그램을위한 확장이며 다른 DBMS에 대해 완전히 새로운 추상화 레이어를 작성할 시간이 없기 때문에 MySQL을 사용합니다.하지만 더 많은 시간이 필요할 때 반드시 살펴볼 것입니다. 대단히 감사합니다 해커 – stone

    1

    난 당신이 그렇게 할 수 있다고 생각하지 않습니다 너무 늦기 UNIQUE 색인을 사용하거나 이와 같은 모든 것을 사용하는 것처럼 "즉시 사용할 수 있습니다".

    여전히 삽입 및 업데이트 전에 트리거되는 트리거를 사용하여 이러한 유형의 검사를 구현할 수 있습니다.

    꽤 언젠가 트리거 함께 일한 적이 없다, 그것은 MySQL을하지 않았다, 그래서 나는 당신에게 예를 줄 수 있지만, 여기에 설명서의 관련 페이지입니다하지 않습니다 12.1.19. CREATE TRIGGER Syntax

    사이드 넘버로서 : 이런 종류의 제약은 여러분이 말했듯이 일반적으로 어플리케이션 측에서 구현됩니다.

    +0

    포인터를 보내 주셔서 감사합니다. 트리거가 원하는대로 작동했습니다! 고맙습니다! – stone

    +0

    당신을 진심으로 환영합니다; 재미있어! –

    관련 문제