2017-02-19 12 views
0

다음과 같은 문제가 있습니다 : 모든 저자는이 이름에 대해 이름과 n 개의 별칭을 가지고 있습니다. 모든 별칭은 원본에서 가져옵니다. 모든 별칭에는 원본이 있습니다.MySQL ON DUPLICATE 다른 테이블에 삽입

CREATE TABLE alias (
    authors_id INT NOT NULL, 
    alias VARCHAR(150) NOT NULL, 
    id INT NOT NULL AUTO_INCREMENT 
    PRIMARY KEY (author_id,alias); 

ID가 외래 키 역할을 예를

AUTHOR| ALIAS | SOURCE 
------------------------- 
Will| Willy |George 
Will| Bill | Jenny 
William| Will| Francis 
William| Bill| Maya 

동안 나는 한 저자에 대한 테이블과 그의 이름, 그의 별칭 모두를위한 하나 있습니다. 여기에 지금은 MySQL이 나는 소스가 별명 소스에 삽입되어 있는지 별명에 저자, 별명, 소스를 삽입 할 때를 위해 문을 삽입 할 필요가있는 소스

CREATE TABLE alias_source (
    id INT NOT NULL AUTO_INCREMENT 
    source VARCHAR(150) NOT NULL, 
    alias_id INT NOT NULL, 
    PRIMARY KEY (id) 
    FOREIGN KEY (alias_id) REFERENCES alias(id); 

에 대한 두 번째 테이블입니다. 중복 별칭에는 새 원본 만 추가됩니다.

답변

0

SQL의 INSERT 문은 한 테이블에만 삽입 할 수 있으며 한 테이블의 열만 나열 할 수 있습니다. source 열은 alias 테이블의 열이 아니기 때문에 INSERT 문에 포함 할 수 없습니다.

트리거를 사용하면 보조 테이블에 삽입 할 수 있지만 트리거는 삽입 할 값을 알아야합니다. 이 경우 트리거에는 source의 값을 가져 오는 방법이 없습니다.

두 개의 INSERT 문으로 수행하는 것이 훨씬 쉬운 작업입니다. 당신의 alias 테이블이 자동 증가 열 id을 가지고 있지만,이 열은 키의 일부가 아니므로

INSERT IGNORE INTO alias SET author_id = ?, alias = ?; 
INSERT INTO alias_source ... 

는하지만 문제가있다. InnoDB에서는 자동 증분 열을 키의 첫 번째 열로 만들어야합니다.

alias_source 테이블에 alias(id)을 참조하는 외래 키가 있지만 허용되지 않습니다. 외래 키는 상위 테이블의 키를 참조해야합니다. 고유 또는 기본 키를 참조해야하며 키의 모든 열을 참조해야합니다 (그렇지 않으면 부모 테이블의 여러 행을 참조 할 수있는 자식 테이블에서 행을 가져오고 의미가 없습니다).

alias 테이블에 자동 증가 열을 사용하려면 기본 키로 만들고 다른 열에 보조 UNIQUE 제약 조건을 지정하십시오.

CREATE TABLE alias (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    authors_id INT NOT NULL, 
    alias VARCHAR(150) NOT NULL, 
    UNIQUE KEY (author_id,alias)); 

그런 다음 삽입 후 id을 쿼리하십시오. 새 행을 삽입했는지 또는 행이 이미 존재하든 선택한 작성자와 별칭이있는 행에 대해 id이 표시됩니다. 귀하의 코멘트에서 후속 질문을 다시

INSERT IGNORE INTO alias SET author_id = ?, alias = ?; 
SELECT id FROM alias WHERE author_id = ? AND alias = ? INTO @id; 
INSERT INTO alias_source SET alias_id = @id, source = ?; 

:

좋은 생각,하지만 당신이하지 생각하는 방법을 작동하지 않습니다. 더미 세트 id=id을 수행하고 세션 변수를 부작용으로 설정할 수 있습니다.

mysql> insert into alias set author_id=1, alias='alias' 
    on duplicate key update id = @id:=id; 

mysql> select @id; 
+------+ 
| @id | 
+------+ 
| NULL | 
+------+ 

하지만 왜 세션 변수를 ID로 설정하지 않았습니까?이 삽입물은 이 아니기 때문에 복제본이 새 행이었습니다. 따라서 id 값은 IODKU가 실행될 때 자동 증가에 의해 아직 생성되지 않았습니다.

당신은 이후 당신이 부작용의 값을 얻을 수 있도록 id 값이 이전 행에 추가 된 중복 것을 행에 대해 동일한 IODKU을 할 경우

mysql> insert into alias set author_id=1, alias='alias' 
    on duplicate key update id = @id:=id; 

mysql> select @id; 
+------+ 
| @id | 
+------+ 
| 1 | 
+------+ 

따라서 @id이 NULL인지 여부를 확인하기 위해 어플 리케이션 코드를 작성하고 @id이 NULL 인 경우 SELECT id 쿼리를 수행해야합니다.

위에서 설명한 것처럼 INSERT IGNORE 다음의 표준 작업으로 SELECT id을 수행하는 것보다 더 복잡한 것처럼 보입니다.

+0

답장을 보내 주셔서 감사합니다 @ 빌! 하지만 ON DUPLICATE KEY를 사용하고 중복 ID를 @id에 저장할 수 있습니까? 두 번째 문장을 건너 뛰려면? –