많이 쓰지만 잘 모르는 Insert

오병진·2022년 9월 28일
1

흔히들 아는 Insert 문이란 다음의 형식과 같다.

insert into {table} (column) values (data)

하지만 PK가 겹친다면 duplicate 에러가 나버린다.
중복된다는 뜻.

그를 위해 ORM에서는 Upsert의 기능이 있다.
Insert하고, 만약 있다면 Update하는 것이다.
그를 위해 먼저 Select을 돌린다.
2개의 구문이 나간다는 것이다.

비효율적이지않은가?

자세하게는 적지않겠다.
나보다 더 잘 정리한 사람들이 있으니

들어가기 귀찮을테니 대략적으로 적자면

Insert INTO person(name, score) Values("Sunrabbit", 123)
ON DUPLICATE KEY UPDATE score = score + VALUES(score);

다음과 같이 이미 있다면, 원래 있던 값에 1을 더한다는 것이다.

그냥 score 로 접근한다면 기존 테이블에 있는 값을, VALUES(score)로 접근한다면 Insert문에 있는 score값에 접근이 된다.

즉 기존 값에 추가가 된다는 것이다.


왜 이런 방식을 사용하냐면, 데이터의 무결성과 정합성을 위함이다.

SELECTUPDATE, INSERT를 묶어 Upsert를 만들어 하나의 트랜잭션으로 하면 되느냐라는 이야기가 있을 수 있다.

그렇다면 레이스컨디션은 어떻게 버틸 것인가?

기존의 값에 추가를 하는 이 방식으로 이를 해결 할 수 있으니 얼마나 좋은가.

기존 Node진영의 ORMPrismaUpsertSELECTUPDATE를 하던 INSERT를 하는 방식이다.

그리고 Mikro ORM의 경우 Insert구문 뒤에 merge기능을 통해 해결하는데, 이는 onConflict이 났을 경우다.

knex라는 SQL Query builder를 이용한 것이다.

추가적으로 PostgreSQL에서는 ON CONFLICT DO UPDATE를 쓴다.

INSERT INTO {table} values ({data})
ON CONFLICT (id) DO UPDATE
SET column_1 = excluded.column_1,
    column_2 = excluded.column_2;

때로는 ORM보다 SQL이 더 직관적이고 편하다.

profile
지나가는 사람입니다. 마저 지나갈게요 :D

0개의 댓글