개요

엑셀에 있는 10만 줄의 데이터를 삽입하는 과정에서 10만번의 insert를 할 경우 232초가 걸렸다.

10만번의 DB I/O 시간 때문인데, UX관점에서 좋지 않았다.

결론적으로, I/O 횟수 단축을 위해 다량의 데이터를 한 번에 insert하는 방법을 찾았다.

 

방법 1

insert의 values 구문에 여러 개의 데이터 Row를 넣는다.

기존

insert into dataset
(ID, FIRSTNAME, LASTNAME, EMAIL)
values
(1, "Gomgom", "Kim", "abc@naver.com")

다중 insert

insert into dataset
(ID, FIRSTNAME, LASTNAME, EMAIL)
values
(1, "Gomgom", "Kim", "abc@naver.com"),
(2, "Gomgom2", "Kim", "abc2@naver.com"),
(3, "Gomgom3", "Kim", "abc3@naver.com"),
(4, "Gomgom4", "Kim", "abc4@naver.com"),
(5, "Gomgom5", "Kim", "abc5@naver.com")

다중 insert Mybatis 표현

<insert id="insertMultiRow" parameterType="java.util.Map">
    insert into dataset
    <trim prefix="(" suffix=")" suffixOverrides=",">
        ID, FIRSTNAME, LASTNAME, EMAIL
    </trim>
    values
    <foreach collection="multiData" item="item" separator=",">
        <trim prefix="(" suffix=")">
            #{item.id,jdbcType=VARCHAR},
            #{item.firstname,jdbcType=VARCHAR},
            #{item.lastname,jdbcType=VARCHAR},
            #{item.email,jdbcType=VARCHAR}
        </trim>
    </foreach>
</insert>

 

주의점

10만개의 데이터 row를 SQL문으로 붙이다 보니

Database 처리 과정에서 mybatis query memory exceeded가 발생했다.

Memory를 늘리는 방법도 있지만 데이터 갯수가 몇 개 까지 늘어날 지 모르는 상황이어서

확실한 해결책은 아니었다.

결론적으로 1만개 까지는 Insert가 되었고,

1만개씩 끊어서 저장하는 방법으로 구현하게 되었다.

 

방법 2

SqlSessionFactory 이용

//쿼리 호출하는 서비스단(기존 소스에서 sqlSessionFactory 부분 외에는 다 생략)

@Autowired
private SqlSessionFactory sqlSessionFactory;

private void test(){
	
    SqlSession sqlSession = null;
    sqlSession = this.SqlSessionFactory.openSession(ExecutorType.BATCH);
        
	while(!startCal.equals(endCal)){
        
        sqlSession.insert("com.test.hubjob.dao.StatBatchDao.insertList", voList); //실행할 쿼리를 insert 해둠.
        loopCnt++;

        //sqlSession 1일단위로 flush(1일 = 144건)
        if(loopCnt % 144 == 0) {
            sqlSession.flushStatements(); //한번에 밀어넣으면 오래걸리므로 적당한 간격으로 끊어서 밀어넣음.
        }
    }
    
    sqlSession.flushStatements(); //남은거 밀어넣고
    sqlSession.commit();	//커밋!(이때 커넥션 한번!)

}

 

 

반응형

 

개요

 

유저 별로 사이트의 메뉴가 다르게 나오기 위해 데이터베이스를 구축한다.

해당 프로그램에선 2 depth의 메뉴 리스트를 만들 예정이다.

 

구현

 

테이블은 2개가 필요하다.

1. 메뉴 테이블

2. 유저 별 사용 가능한 메뉴 표시 테이블

 

1. 메뉴 테이블

 

칼럼 정보

IDX NAME NAME_KR PATH PARENT_IDX
pk 영어이름(키로 사용) 한글이름(UI로 사용) 프론트 경로 상단 태그

 

IDX : PK

NAME : 메뉴 탭의 영어 이름으로써 프런트에서 키로 연결하기 위해 필요하다.

NAME_KR : 메뉴 탭의 한글 이름으로써 프론트에서 UI로 나타내기 위해 필요하다.

PATH : 프론트에서 사용하는 실제 경로이다.

PARENT_IDX : 상위 메뉴의 IDX를 나타낸다. SELF JOIN을 통하여 메뉴를 연결할 예정이다

.

2. 유저 별 사용 가능한 메뉴 표시 테이블

 

칼럼 정보

USER_IDX MENU_IDX AUTH
유저 IDX(외래키) 메뉴 IDX(외래키) 사용 가능 여부 1 / 0

 

USER_IDX : 유저 테이블의 IDX를 외래 키로 가진 것 - 유저 별 메뉴 사용 여부 표시 위함

MENU_IDX : 메뉴 테이블의 IDX를 외래키로 가진 것

AUTH : 해당 유저가 해당 메뉴를 사용할 수 있는지 1과 0으로 나타낸 것 (1: 사용 / 0: 사용불가)

 

사용

 

메뉴 테이블을 SELF JOIN 한 후 유저 별 사용 가능 테이블을 INNER JOIN 하여

유저 별로 AUTH가 1인 메뉴 및 서브메뉴를 mybatis를 통해 불러올 예정이다. 

mybatis 관련 참고

2021.06.29 - [Spring] - [Spring] 유저별로 메뉴 다르게 보이기

 

[Spring] 유저별로 메뉴 다르게 보이기

데이터 베이스 구축은 해당 게시물을 참조한다. 2021.06.28 - [Database] - [Database] 유저별로 메뉴 다르게 보이기 [Database] 유저별로 메뉴 다르게 보이기 개요 유저 별로 사이트의 메뉴가 다르게 나오기

gomgomkim.tistory.com

 

반응형

 

개요

 

workbench에서 csv 파일을 import 하여 한번에 데이터를 입력한다.

서로 다른 DB 서버에서 테이블을 복사하거나

엑셀 형식의 데이터 파일을 한 번에 삽입할 때 활용할 수 있다.

 

방법

 

1. 삽입을 원하는 테이블을 마우스 우클릭 하여 Table Data Import Wizard를 클릭한다.

 

2. csv 파일을 선택한 후 Next를 누른다.

 

3. 기존 테이블을 선택한 후 Next를 누른다.

새 테이블을 만들 예정이라면 아래 항목을 선택하여 테이블 명을 입력하면 된다.

 

[중요] 4. 테이블 컬럼명과 csv컬럼명을 매핑한다.

기본적으로 같은 이름으로 매핑해주지만,

가끔 다르게 매핑되거나 다른 이름은 자동으로 다른 값으로 매핑된다.

해당 부분은 사용자가 직접 매핑해야한다.

 

5. Next 두 번 누르면 완료된다.

 

반응형

 

이슈

 

기존 테이블 내에서 기본키의 Auto Increment 설정을 적용할 때 적용되지 않는 오류가 있었다.

 

 

원인

 

해당 키가 다른 테이블의 외래키로 잡혀있었기 때문에 Auto Increment 설정을 할 수 없다는 것이었다.

 

Error 1833: Cannot change column 'IDX'
: used in a foreign key constraint '[외래키 인덱스]' of table '[테이블 명]' 

SQL Statement: ALTER TABLE `[테이블 명]`  CHANGE COLUMN `IDX` INT(11) NOT NULL AUTO_INCREMENT

 

 

해결 방법

 

SET FOREIGN_KEY_CHECKS = 0; 을 붙여서 외래키 검사를 무시하게 만든다.

 

SET FOREIGN_KEY_CHECKS = 0;

ALTER TABLE `[테이블 명]` 
CHANGE COLUMN `IDX` INT(11) NOT NULL AUTO_INCREMENT ;

 

반응형

+ Recent posts