Mysql Select-Insert

김민창·2024년 6월 1일
0
post-thumbnail
post-custom-banner

사내에서 데이터베이스를 마이그레이션할때 항상 스크립트를 작성했었는데, mysql의 이런 기능도 있었다

오래전부터 사용되던 데이터베이스들은 테이블 구조가 구린경우가 많다.

  • 더이상 사용하지 않는 컬럼
  • 과한 정규화
  • 엄청난 반정규화

하여간 다양한 상황에 직면하게 되는데, 개선건으로 테이블의 정규화가 필요하다고 생각하고, 스크립트를 준비하려했는데, 옆에서 그거 쿼리 한줄이면 끝나는데 라며 직접 쿼리를 작성해줬다.


Insert - Select

  • 그러니깐 select 된 결과값들을 모두 insert 할 수 있다.
  • 예를들면 다음과 같은 쿼리가 있겠다
insert into table_1 (name)
  select table_2.name
  from table_2 where table2.id > 10;
  • 다음 select 절의 결과값을 table_1.name 필드에 전부 넣겠다 라는 뜻이다.
  select table_2.name
  from table_2 where table2.id > 10;

  • 그리고 전체 테이블을 옮기는 방법도 있는데
insert into table_1 table table_2
  • 위의 sql 문은 다음 쿼리와 동일하다
insert into table_1
  select * from table_2

  • 모종의 사유로 insert 처리중 에러가 발생한다면 롤백과 동시에 종료를 하게 되는데, 이때 insert ignore를 사용하면 에러를 발생할 수 있는 레코드를 제외하고 구문을 실행하게 된다
insert ignore into table_1
  select * from table_2

  • 동일한 테이블에 서브쿼리로 insert 하는것은 안된다-로 읽히는데 재현이 안된다...

    고수들의 도움이 필요


당장써보자?

  • 아주 좋다 그래서 당장 쓰고싶긴하지만 사내에 쿼리를 날리기에는 조금 찜찜한 부분이 있기에 조금 수정을 해보도록 하자

  • 기존 테이블 구조

  • address 필드를 정규화 하여, 다음과 같은 테이블 구조를 갖고싶다!

  • 사실 다음과 같은 select-insert 쿼리로 한번에 가능하긴하다!
insert into `정규화 할 테이블` (new_address, fk_id)
  select name, id from `기존 테이블`
  • 하지만 중간에 에러가 터진다면..!!
    멱등성이 보장되는 쿼리로 좀더 편안하게 쿼리를 변경하자
insert into `정규화 할 테이블` (new_address, fk_id)
	select name, id from `기존 테이블`
	where not exists (
    				select * from `정규화 할 테이블` 
  					where `정규화 할 테이블`.fk_id = `기존 테이블`.id
                    )
  • 존재하지 않는 레코드만 삽입이 가능하다!

출처 : mysql 문서

profile
개발자 팡이
post-custom-banner

0개의 댓글