코딩과 결혼합니다

[Game_Crew] 성능 테스트 : Java Faker 를 사용하여 더미데이터 생성하기 본문

코딩과 매일매일♥/Game_Crew

[Game_Crew] 성능 테스트 : Java Faker 를 사용하여 더미데이터 생성하기

코딩러버 2023. 12. 27. 17:28
728x90
Mockaroo를 사용하면 최대 1000개의 데이터만을 생성할 수 있다. 생각해 보니 나는 100만 ~200만 건의 데이터를 생성해야 하는데 너무 번거로울 듯하여 Java Faker를 통해서 나머지 더미데이터들을 생성해보고자 한다.

 

 

📌 Java Faker Dependency (Gradle)

dependencies {
    implementation 'com.github.javafaker:javafaker:1.0.2'
}

 

 

📌 Faker 클래스의 다양한 메서드 제공 예시

Faker faker = new Faker();

String name = faker.name().fullName(); // Miss Samanta Schmidt
String firstName = faker.name().firstName(); // Emory
String lastName = faker.name().lastName(); // Barton

String streetAddress = faker.address().streetAddress(); // 60018 Sawayn Brooks Suite 449

int age = faker.number().numberBetween(20,30);

 

 

📌더미 데이터 생성

record_of_ratings(평가받은 내역), post 테이블의 더미 데이터를 순차적으로 추가해 보기로 하였다.
필요하면 user 데이터도 더 추가할 계획이다.

유저 1000 / 10만 (9만 9000+) / 20만 (10만 +) /++
post 10만 / 30만 (20만+) / 50만 (20만+) /++
record_of_rating 20만 / 50만 1000 (30만+) / 80만 1000 (30만+) /++

total_rating 약 1000 / 약 10만 / 약 20만 (더미데이터 x)

총 30만 / 100만 / 170만 / ++ 의 데이터를 가지고 성능 테스트 시작!

 


코드 예시 (데이터 확인을 위해 100개만 추가)

package com.gamecrew.gamecrew_project.global.faker;

import com.gamecrew.gamecrew_project.domain.post.type.CategoryType;
import com.github.javafaker.Faker;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Configuration
@PropertySource("classpath:application.properties")
public class DummyDataGenerator {
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String user;
    @Value("${spring.datasource.password}")
    private String password;

    @Bean
    public void generateData(){
        try(Connection conn = DriverManager.getConnection(url, user, password)) {
            Faker faker = new Faker();

            String query = "INSERT INTO post (created_at, modified_at, category, content, current_num, post_view_count, title, total_number, view, user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            PreparedStatement pstmt = conn.prepareStatement(query);

            CategoryType[] categories = CategoryType.values();


            for (int i = 0; i < 100; i++) {
            	//생성날짜
                Date startDate = new SimpleDateFormat("yyyy.MM.dd").parse("2022.11.23");
                Date endDate = new SimpleDateFormat("yyyy.MM.dd").parse("2023.12.21");
                java.util.Date createdDate = faker.date().between(startDate, endDate);
                pstmt.setTimestamp(1, new java.sql.Timestamp(createdDate.getTime()));

                // 생성된 날짜 이후의 날짜를 수정된 날짜로 설정
                java.util.Date modifiedDate = faker.date().future(365, TimeUnit.DAYS, createdDate);
                pstmt.setTimestamp(2, new java.sql.Timestamp(modifiedDate.getTime()));

				// 무작위로 카테고리를 선택합니다. 카테고리는 설정해놓은 Type들로만.
                CategoryType randomCategory = categories[faker.random().nextInt(categories.length)]; 
                pstmt.setString(3, randomCategory.name());

				//content
                pstmt.setString(4, faker.lorem().sentence());

                //total_num 1~25 사이의 랜덤한 숫자
                long totalNumber = (long)faker.random().nextInt(1, 25);
                pstmt.setLong(8, totalNumber);

                //current_num 0~totalNumber 사이의 랜덤한 수 생성
                pstmt.setLong(5, (long)faker.random().nextInt((int)totalNumber));

                //post_view
                pstmt.setLong(6, (long)faker.random().nextInt(10000));

                //title
                pstmt.setString(7, faker.lorem().sentence());

                //view
                pstmt.setLong(9, (long)faker.random().nextInt(10000));

                //user_id 현재 유저의 수가 1000명
                pstmt.setLong(10, faker.random().nextLong(1000));

                pstmt.executeUpdate();

            }
        } catch (SQLException | ParseException e) {
            throw new RuntimeException(e);
        }
    }
}

 

📌Java와 JDBC를 사용하여 MySQL 데이터베이스에 연결하고 데이터를 저장

Mockaroo를 사용했을 때보다 저장 속도가 훨씬 빠르고, 세밀하게 원하는 형태의 데이터를 한 번에 많이 저장할 수 있다.

 


이후 10만 개의 데이터를 저장하려 하였으나 SQL 쿼리 실행 중 제약 조건 위반 문제가 발생으로 오류가 나게 되었다.

user 테이블에 존재하지 않는 user_id를 post 테이블에 추가하려고 시도하여 생기는 오류로 보였다.

 

                //user_id 현재 유저의 수가 1000명
                pstmt.setLong(10, faker.random().nextLong(1000));

코드를 살펴보니 0부터 999까지의 무작위 값을 생성하고 있다. user테이블에는 1번부터 1000번까지의 user_id가 존재한다. 

 

                //user_id
                pstmt.setLong(10, 1L + faker.random().nextLong(1000));

1부터 1000까지 무작위 값을 생성할 수 있도록 1을 더하였다.
이후 문제없이 더미데이터를 생성 / 저장할 수 있었다.