[DB] 데이터베이스 마이그레이션 삽질의 과정 (MongoDB -> MySQL)

kihongsi·2022년 2월 23일
1

DB

목록 보기
2/3
post-thumbnail

기존 Node.js + MongoDB 조합의 서비스를 SpringBoot + MySQL로 다시 구현하는 과정에 있다.
오늘은 mongoDB의 데이터를 새로 사용할 rds MySQL로 옮기는 것을 도전했다.

데이터베이스 마이그레이션이란?

마이그레이션이란 어떤 운영환경으로부터 다른 운영환경으로 옮기는 작업을 뜻한다.
DB 마이그레이션이란 말 그대로 데이터베이스의 스키마를 관리하기 위해 전환하는 것이다.
좁은 의미로는 프로젝트 상의 테이블 생성 및 변경 작업을 말하고, 넓게 보면 DB 어플리케이션 또는 시스템 자체를 옮기는 것을 일컫는다.

마이그레이션 방법

데이터를 옮기는 방법에는 여러가지가 있다.

  • export/import
  • 직접 로딩 (Direct Loading)
  • 테이블스페이스 이동
  • 테이블 이동
  • 백업 본을 이용한 데이터 마이그레이션
  • SQL LOADER

나의 경우는 nosql인 MongoDB에서 rdbms인 MySQL로 옮겨야 했기 때문에 export/import 방식을 사용하려고 했다.

MongoDB 데이터를 csv파일로 Export하기

먼저 기존 mongoDB 데이터를 csv 파일 형식으로 export 해주었다.

  1. homebrew로 MongoDB 툴 설치하기
    brew tap mongodb/brew
    brew install mongodb-database-tools

  2. mongoexport를 적절한 옵션과 함께 실행하기

mongoexport --uri=[mongoDB uri] --collection=[schema명] 
--type=csv --fields=[export할 column명 나열(띄어쓰기 없이 콤마로 구분)] 
--out=[output 파일명(확장자는 csv)]

csv 확장자 말고 json 형식으로도 export할 수 있다.
그런데 json으로 하니까 오브젝트ID타입인 기존 MongoDB의 '_id' 필드가 포함되어서 불편했다.
mysql로 import할 때는 csv가 더 편한 것 같다.

mongoexport 공식 문서
여기에 아주 자세하게 나와 있으니 보고 따라치기만 하면 된다.

MySQL에서 csv 파일 Import하기

만들어진 csv 파일을 MySQL로 import하는 방법에도 여러가지가 있다.

Workbench 활용하기

스키마 위에서 마우스 오른쪽 커서를 누르면 'Table Data Import Wizard' 버튼이 뜬다.
아까 만들어둔 파일을 선택하고 진행하면 된다!
이 방법으로 스무스하게 될 줄 알았으나..

위의 오류가 발생했다.
구글링을 해보니 다 파일 인코딩의 문제라고 해서 workbench 인코딩 설정도 바꿔보고, csv 파일 인코딩도 utf-8로 다시 해보고, 로컬 MySQL 설정도 바꿔보고 재부팅하고 이것저것 다했지만 실패했다. m1맥북 문제인가?
결국 스크립트를 활용하기로 했다.

스크립트 활용

파이썬 스크립트와 SQL 스크립트를 활용하는 방법이 있다.
파이썬의 경우 pandas에서 제공하는 to_sql 메소드를 사용할 수 있다고 한다.
pandas.DataFrame.to_sql — pandas 1.4.1 documentation
이 방법은 공식 문서를 참조하도록 하자.

나는 SQL Script를 작성하는 방식을 택했다.
LOAD DATA INFILE 구문을 사용하면 파일을 import할 수 있다.

LOAD DATA LOCAL INFILE '[아까 만든 csv 파일]'
INTO TABLE [schema].[table]
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
IGNORE 1 LINES /* csv 파일의 첫 줄은 column명이니 제외해야 함 */
(column1, column2, ...) /* 사용할 column명 나열 (순서 중요) */

이런 식으로 작성해 주었다.

스크립트를 작성했으면 MySQL에 접속해서 해당 파일을 실행시켜주어야 한다.
실행하기 전 먼저 secure_file_priv 설정과 local_infile 설정을 바꿔줘야 한다.

[MySQL] Load Data 시도 중 secure_file_priv 문제 직면
MySQL | load data infile ERROR

설정을 마쳤으면 바로 실행 고고

mysql -u [user] -p
source [sql script 파일 경로]

이러면 실행이 된다.

근데 여기서 문제가 하나 있었다.
sql 스크립트에 FIELDS TERMINATED BY ","를 씀으로써 콤마를 기준으로 컬럼을 구분하게 되는데, 필드의 문자열 안에도 콤마가 있었던 것이다...
01, "금02,03,04/3-107" , , 3, 주간, N, ... 요런식으로..
그럼 ,를 기준으로 나뉘니까 "금02 03 04/3-107"이런 결과가 나오게 되는 것!

구글링 결과
OPTIONALLY ENCLOSED BY '"'
스크립트에 이 한 줄을 추가해주면 해결된다.

여기까지 하면 원하는 테이블의 내용이 잘 옮겨진 것을 확인할 수 있다.

0개의 댓글