데이터베이스 연결 및 데이터 가져오기

데이터베이스 연결 및 데이터 가져오기 (Connect and retrieve data from databases)

대규모 데이터가 데이터베이스에 쌓여 있을 때 Kotlin DataFrame을 쓰면 SQL 쿼리 없이도 손쉽게 그 데이터를 불러와 분석할 수 있어요. 이 글에서는 Kotlin DataFrame으로 데이터베이스에 연결하고, 스키마를 확인하고, 테이블이나 SQL 쿼리로 데이터를 불러오는 흐름을 예제를 따라 배워볼게요.

출처: Kotlin 공식 문서

본문

Kotlin DataFrame 라이브러리는 가장 널리 쓰이는 SQL 데이터베이스를 지원해요.

GitHub의 Kotlin DataFrame SQL 예제도 함께 살펴보세요.

시작하기 전에

IntelliJ IDEA 2026.2부터 Kotlin Notebook은 더 이상 IDE에 번들로 포함되지 않고, JetBrains에서 공식 지원하지도 않게 돼요. 소스 코드는 GitHub에 계속 남아 있어요.

자세한 내용은 블로그 포스트에서 확인할 수 있어요.

이 튜토리얼을 따라 하려면:

  1. File | New | Kotlin Notebook을 선택해요.

  2. 노트북의 첫 번째 셀에 사용할 데이터베이스의 JDBC(Java Database Connectivity) 드라이버 의존성을 추가해요.

    예를 들어 MariaDB 데이터베이스에 연결하려면 다음을 추가해요:

    USE {
       dependencies("org.mariadb.jdbc:mariadb-java-client:$version")
    }
    
  3. Kotlin DataFrame을 가져와요:

    %use dataframe
    

    다른 코드 셀보다 먼저 %use dataframe 줄이 있는 코드 셀을 실행해서, 노트북에서 DataFrame 라이브러리와 그 API를 사용할 수 있게 준비해 두세요.

    튜토리얼을 따라 하려면 DataFrame을 Gradle이나 Maven 의존성으로 사용할 수도 있어요.

데이터베이스에 연결하기

데이터베이스에 연결하려면 DbConnectionConfig() 함수로 연결 설정을 만들어요.

  1. 다음 기능들을 가져와요:

    import org.jetbrains.kotlinx.dataframe.io.DbConnectionConfig
    import org.jetbrains.kotlinx.dataframe.schema.DataFrameSchema
    
  2. DbConnectionConfig() 함수로 연결 파라미터(URL, 사용자 이름, 비밀번호)를 정의해요:

    val URL = "YOUR_URL"
    val USER_NAME = "YOUR_USERNAME"
    val PASSWORD = "YOUR_PASSWORD"
    
    val dbConfig = DbConnectionConfig(URL, USER_NAME, PASSWORD)
    

SQL 데이터베이스에 연결하는 방법에 대한 더 자세한 내용은 Kotlin DataFrame 문서의 SQL 데이터베이스에서 읽기를 참고해요.

데이터베이스 스키마 확인하기

데이터를 불러오기 전에 데이터베이스 스키마를 확인해서 어떤 테이블이 있고 각 테이블에 어떤 컬럼이 있는지 파악하는 게 좋아요. 스키마를 보면 어떤 테이블을 DataFrame으로 불러올지 결정할 수 있어요.

데이터베이스에 있는 사용자 생성 테이블의 모든 스키마를 가져오려면 DataFrameSchema.readAllSqlTables() 함수를 사용해요:

val dataSchemas = DataFrameSchema.readAllSqlTables(dbConfig)

dataSchemas.forEach { (tableName, schema) ->
    println("---Schema for table: $tableName---")
    println(schema)
    println()
}

데이터 불러오기

데이터베이스 스키마를 확인하고 데이터를 고른 다음에는, 그 데이터를 DataFrame으로 불러와요.

Kotlin DataFrame은 데이터베이스에서 데이터를 불러오는 두 가지 방법을 제공해요.

  • 테이블에서 직접 데이터를 불러오기.

  • 사용자 정의 SQL 쿼리의 결과를 불러오기.

두 방법 모두 데이터를 확인하고, 변환하고, 분석할 수 있는 DataFrame을 반환해요.

테이블에서 데이터 불러오기

테이블에서 데이터를 불러오려면 DataFrame.readSqlTable() 함수를 사용해요.

다음 예제는 movies 테이블에서 처음 100개 행을 불러와요:

val moviesDf = DataFrame.readSqlTable(
    dbConfig = dbConfig,
    tableName = "movies",
    limit = 100
)

moviesDf

SQL 쿼리로 데이터 불러오기

데이터베이스에 특정 SQL 쿼리를 실행하려면 DataFrame.readSqlQuery() 함수를 사용해요. 이 방법은 특정 컬럼만 가져오거나, 테이블을 조인하거나, 행을 필터링하거나, 데이터베이스에서 집계를 해야 할 때 유용해요.

Quentin Tarantino 감독의 영화와 관련된 특정 데이터셋을 가져와 볼게요. 이 쿼리는 영화 상세 정보를 선택하고 각 영화의 장르를 합쳐요:

val TARANTINO_FILMS_SQL_QUERY = """
    SELECT name, year, rank, GROUP_CONCAT(genre) as "genres"
    FROM movies JOIN movies_directors ON movie_id = movies.id
    JOIN directors ON directors.id=director_id LEFT JOIN movies_genres ON movies.id = movies_genres.movie_id
    WHERE directors.first_name = "Quentin" AND directors.last_name = "Tarantino"
    GROUP BY name, year, rank
    ORDER BY year
    """

val tarantinoMoviesDf = DataFrame.readSqlQuery(dbConfig, TARANTINO_FILMS_SQL_QUERY)

tarantinoMoviesDf

데이터 처리하기

데이터베이스를 DataFrame으로 불러온 다음에는 DataFrame 연산을 사용해 가져온 데이터를 처리할 수 있어요.

예를 들어 앞에서 만든 데이터를 다뤄 볼게요. 다음 코드는:

  1. .fillNA() 함수로 year 컬럼의 누락 값을 채워요.

  2. .convert() 함수로 컬럼을 Int로 변환해요.

  3. .filter() 함수로 2000년 이후에 개봉한 영화만 남겨요.

val filteredTarantinoMovies = tarantinoMoviesDf
    .fillNA { year }.with { 0 }
    .convert { year }.toInt()
    .filter { year > 2000 }

filteredTarantinoMovies

데이터 분석하기

DataFrame 라이브러리를 사용해 데이터를 그룹화하고, 정렬하고, 집계하면 데이터 속 패턴을 발견하고 이해할 수 있어요.

예를 들어 actors 테이블에서 배우 데이터를 읽고 가장 흔한 이름 20개를 찾아 볼게요:

// Extract data from the actors table
val actorDf = DataFrame.readSqlTable(dbConfig, "actors", 10000)
val top20ActorNames = actorDf
   // Groups the data by the first_name column
   .groupBy { first_name }
   
   // Counts the occurrences of each unique first name
   .count()
   
    // Sorts the results in descending order of count
   .sortByDesc("count")
    
   // Selects the top 20 most frequent names for analysis.
   .take(20)

다음 단계