2012-03-21 1 views
3

작은 인덱스 테이블에서 행과 교차하는 데이터 테이블의 행을 업데이트하려고합니다. 두 테이블은 데이터 테이블의 복합 PK에 조인되며 동일한 기준을 사용하는 explain-select는 인덱스가 제대로 사용되고 정확하게 고유 한 행을 가져 오는 것을 보여줍니다. 그러나 여전히 업데이트에 문제가 있습니다.복합 키로 조인 된 테이블에 대한 업데이트

임시 테이블에 단 하나의 행이있을 때 조인 된 테이블의 업데이트가 제대로 작동하지만 더 많은 행이있을 경우 MySql Error 1175이 표시되고 지정한 WHERE 조건이 인식되지 않습니다.

안전 모드를 SET SQL_SAFE_UPDATES = 0으로 해제 할 수 있다는 것을 알고 있지만 누구나 내가 여기에 대해 이해하지 못한다고 말할 수 있습니까? 내 WHERE 조건이 받아 들여지지 않는 이유는 무엇이며 왜 NATUAL JOIN을 수행 할 때 어디에 위치가 필요합니까? 그리고이 작업이 오른쪽 테이블 (MyTempTable)의 한 행에서만 작동하는 이유는 무엇입니까?

강령 아래

은 크게 단순화하지만, 테이블 내 문제를 나타내는 & 업데이트를 만드는 구조적으로 동일하다.

 
-- The Data Table. 
Create Table MyDataTable 
(
    KeyPartOne int not null, 
    KeyPartTwo varchar(64) not null, 
    KeyPartThree int not null, 
    RelevantData varchar(200) null, 
    Primary key (KeyPartOne, KeyPartTwo, KeyPartThree) 
) Engine=InnoDB; 

-- The 'Temp' table. 
Create Table MyTempTable 
(
    KeyPartOne int not null, 
    KeyPartTwo varchar(64) not null, 
    KeyPartThree int not null, 
    Primary key (KeyPartOne, KeyPartTwo, KeyPartThree) 
)Engine=Memory; 

-- The Update Query (works fine with only 1 row in Temp table) 
update MyDataTable natural join MyTempTable 
set RelevantData = 'Something Meaningful'; 

-- Specifying 'where' - roduces same effect as the other update query 
update MyDataTable mdt join MyTempTable mtt 
on mdt.KeyPartOne = mtt.KeyPartOne 
and mdt.KeyPartTwo = mtt.KeyPartTwo 
and mdt.KeyPartThree = mtt.KeyPartThree 
set RelevantData = 'Something Meaningful' 
where mdt.KeyPartOne = mtt.KeyPartOne 
and mdt.KeyPartTwo = mtt.KeyPartTwo 
and mdt.KeyPartThree = mtt.KeyPartThree; 

P. temp 테이블에 하나의 행만 포함되어 있으면 위의 두 명령문 모두 예상대로 작동하지만 두 개 이상의 행이있을 때 오류가 발생합니다. 왜 그런지 궁금 하네!

답변

1

MySql 포럼에서는 업데이트 쿼리가 유효하며 워크 벤치에서 안전 업데이트 모드로 작동하지 않는다는 사실이 인덱스에 문제가 없음을 나타내지 않습니다. 그것은 Workbench의 "don-t-yourself-in-the-foot"모드의 단점입니다. :-)

2

첫 번째 UPDATE 쿼리에서 NATURAL JOIN을 사용하면 NATURAL LEFT JOIN과 같습니다.

두 번째 UPDATE 쿼리에서 INNER JOIN과 같은 JOIN을 사용합니다.

LEFT JOININNER JOIN과 동일하지 않으며 NATURAL JOINJOIN과 동일하지 않습니다.

하지 당신이해야 할 노력하고 있지만 해당 항목이 MyTempTable에 존재 MyDataTable의 모든 행을 업데이트하려는 경우,이 쿼리는 트릭 무엇을해야하는지 확인하십시오 그게 아니라면

UPDATE 
    myDataTable mdt 
    INNER JOIN MyTempTable mtt ON 
     mdt.KeyPartOne = mtt.KeyPartOne 
     AND mdt.KeyPartTwo = mtt.KeyPartTwo 
     AND mdt.KeyPartThree = mtt.KeyPartThree 
SET 
    mdt.RelevantData = 'Something Meaningful' 

을 당신이하려는 일이 무엇인지 명확히하고 대답을 업데이트 할 것입니다.

+0

"NATURAL JOIN (NATURAL JOIN, NATURAL LEFT JOIN과 동일)"에 대한 출처를 인용 할 수 있습니까? [맨페이지] (http://dev.mysql.com/doc/refman/5.0/en/join.html)에 따르면 - 'join processing changes'까지 아래로 스크롤하십시오 - 자연 결합은 equivi-join과 동일합니다 'USING'은 지정된 필드의 내부 조인으로 해석됩니다. 또한, 나는 또한 당신이 제안한 것을 시도했다. - 이것은 두 번째 질의인데, "- Specify 'where' '아래에있다. 그것은 여전히 ​​누락 된 키에 대해 불만을 제기 했으므로 제공했지만 유효한 키로 인식되지는 않습니다. –

+0

@ValAkkapeddi : 아마 내가 틀렸어. 저는 같은 페이지를 보았습니다. "NATURAL JOIN"은 NATURAL LEFT JOIN과 동일하지만, 다시 한번 살펴보면 "NATURAL JOIN"은 "NATURAL LEFT JOIN"과 같습니다. 나는 그것이 옳지 않을지도 모른다는 것을 깨닫는다.또한, 나는 당신의 질문을 완전히 이해하지 못했다는 것을 깨달았고, 당신이 안전한 업데이트 모드에 있기 때문에 MySQL이 에러를 던지고 있다는 것이 문제이다. 죄송 합니다만 안전 업데이트 모드의 단점에 대한 경험이 없습니다. – Travesty3

+0

어쨌든 시도하는 타이! MySql이 복합 인덱스를 사용하는 방법에 대해 무엇이 궁금해합니다. 희망을 누군가가 이것을 설명 할 수 있습니다! –