programing

MariaDB: 다중 테이블 업데이트가 단일 행을 여러 번 업데이트하지 않습니까?왜요?

testmans 2023. 6. 19. 21:16
반응형

MariaDB: 다중 테이블 업데이트가 단일 행을 여러 번 업데이트하지 않습니까?왜요?

오늘 나는 예상치 못한 것에 그냥 뒤통수를 맞았어요.다음은 문제를 재현하기 위한 작은 스크립트입니다.

create temporary table aaa_state(id int, amount int);
create temporary table aaa_changes(id int, delta int);

insert into aaa_state(id, amount) values (1, 0);
insert into aaa_changes(id, delta) values (1, 5), (1, 7);

update aaa_changes c join aaa_state s on (c.id=s.id) set s.amount=s.amount+c.delta;

select * from aaa_state;

최종 결과는 다음과 같습니다.aaa_state테이블:

아이디
1 5

반면에 저는 다음과 같이 예상합니다.

아이디
1 12

왜 그러고 있어?문서를 확인했지만 이 동작에 대한 힌트를 찾을 수 없습니다.이것은 제가 보고해야 하는 버그인가요, 아니면 의도적으로 보고해야 하는 버그인가요?

표시되는 동작은 에서 발생하는 두 가지 업데이트와 일치합니다.aaa_state표. 한 업데이트는 금액을 7로 할당하고, 두 번째 업데이트는 이 금액을 5로 설정합니다.이는 MySQL이 스냅샷을 사용하여 설명할 수 있습니다.aaa_state가져올 테이블amount업데이트의 각 단계에 대해.사실일 경우 실제 단계는 다음과 같습니다.

1. join the two tables
2. update the amount using the "first" row from the changes table.
   now the cached result for the amount is 7, but this value will not actually
   be written out to the underlying table until AFTER the entire update
3. update the amount using the "second" row from the changes table.
   now the cached amount is 5
5. the update is over, write 5 out for the actual amount

구문이 원하는 작업에 적합하지 않습니다.다음과 같은 것을 사용해야 합니다.

UPDATE aaa_state as
INNER JOIN
(
    SELECT id, SUM(delta) AS delta_sum
    FROM aaa_changes
    GROUP BY id
) ac
    ON ac.id = as.id
SET
    as.amount = as.amount + ac.delta_sum;

여기서 우리는 각각의 델타 값을 적절하게 집계하고 있습니다.id비밀리에 말입니다.이것은 MySQL이 조인을 수행하기 전에 델타 합계가 적절하게 계산되고 하위 쿼리에서 구체화되어 첫 번째 테이블을 업데이트한다는 것을 의미합니다.

언급URL : https://stackoverflow.com/questions/67868164/mariadb-multiple-table-update-does-not-update-a-single-row-multiple-times-why

반응형