Introduction to ClickHouse Database

1. 개요

온라인 분석 처리(OLAP)를 활용함으로써 기업은 현재 운영에 대한 통찰을 얻고 개선을 위한 트렌드를 식별할 수 있습니다. 이는 일반적으로 집계된 비즈니스 데이터에 대해 복잡한 분석을 수행함으로써 이루어집니다.

ClickHouse 덕분에 최근 인기를 얻고 있습니다.

이번 튜토리얼에서는 ClickHouse 데이터베이스를 Spring Boot 애플리케이션에 통합하는 방법을 살펴보겠습니다. 필요 구성, 연결 설정 및 데이터베이스 테이블에 대한 CRUD 작업을 수행하는 과정을 안내하겠습니다.

2. 프로젝트 설정하기

ClickHouse 데이터베이스와 상호작용하기 전에 몇 가지 SDK 종속성을 포함하고 애플리케이션을 올바르게 구성해야 합니다.

2.1. 종속성

우리 프로젝트의 pom.xml 파일에 필요한 종속성을 추가해보겠습니다:

<dependency>
    <groupId>com.clickhouse</groupId>
    <artifactId>clickhouse-jdbc</artifactId>
    <version>0.7.1</version>
</dependency>
<dependency>
    <groupId>org.lz4</groupId>
    <artifactId>lz4-java</artifactId>
    <version>1.8.0</version>
</dependency>

clickhouse-jdbc 종속성JDBC API의 구현을 제공하며 ClickHouse 데이터베이스와 연결을 설정하고 상호작용할 수 있게 해줍니다.

기본적으로 ClickHouse는 데이터를 저장할 때 LZ4 압축을 사용하므로, 이에 대한 lz4-java 종속성도 추가했습니다.

2.2. Flyway를 사용하여 데이터베이스 테이블 정의하기

다음으로 작업을 수행할 데이터베이스 테이블을 정의해 보겠습니다.

Flyway를 사용하여 데이터베이스 마이그레이션을 관리할 것입니다. flyway-core(링크)와 flyway-database-clickhouse(링크) 종속성을 포함합시다:

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-database-clickhouse</artifactId>
    <version>10.16.3</version>
</dependency>

이 종속성을 pom.xml에 추가한 후, src/main/resources/db/migration 디렉토리에 V001__create_table.sql이라는 마이그레이션 스크립트를 생성하고 다음 내용을 추가합니다:

CREATE TABLE authors (
    id UUID,
    name String,
    email String,
    created_at DateTime
)
ENGINE = MergeTree()
PRIMARY KEY id;

우리 스크립트는 id를 기본 키로 가지고 있는 authors 테이블을 생성하며, 몇 개의 다른 열도 포함되어 있습니다. MergeTree 테이블 엔진을 사용하여 삽입과 쿼리 성능을 최적화하였습니다.

2.3. 데이터 모델

마지막으로 authors 테이블의 데이터를 표현하기 위해 Author 레코드를 생성합니다:

public record Author(
    UUID id,
    String name,
    String email,
    LocalDateTime createdAt) {

    public static Author create(String name, String email) {
        return new Author(
            UUID.randomUUID(),
            name,
            email,
            LocalDateTime.now()
        );
    }
}

우리는 또한 임의의 UUID와 현재 타임스탬프를 사용하여 Author 레코드를 인스턴스화하는 정적 create() 메서드를 추가합니다.

3. 테스트 컨테이너로 로컬 테스트 환경 설정하기

로컬 개발 및 테스트를 용이하게 하기 위해 Testcontainers를 사용하여 ClickHouse 데이터베이스를 설정할 것입니다.

Testcontainers를 통해 데이터베이스를 실행하려면 활성화된 Docker 인스턴스가 필요합니다.

3.1. 테스트 종속성

먼저, pom.xml 파일에 필요한 테스트 종속성을 추가하겠습니다:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-testcontainers</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>clickhouse</artifactId>
    <scope>test</scope>
</dependency>

spring-boot-testcontainersclickhouse 테스트 컨테이너 모듈 종속성은 ClickHouse 데이터베이스를 위한 일시적인 Docker 인스턴스를 시작하는 데 필요한 클래스를 제공합니다.

3.2. 테스트 컨테이너 빈 정의하기

이제 @TestConfiguration 클래스를 생성하여 테스트 컨테이너 빈을 정의해 보겠습니다:

@TestConfiguration(proxyBeanMethods = false)
class TestcontainersConfiguration {

    @Bean
    public ClickHouseContainer clickhouseContainer() {
        return new ClickHouseContainer("clickhouse/clickhouse-server:24.11");
    }

    @Bean
    public DynamicPropertyRegistrar dynamicPropertyRegistrar(ClickHouseContainer clickhouseContainer) {
        return registry -> {
            registry.add("spring.datasource.url", clickhouseContainer::getJdbcUrl);
            registry.add("spring.datasource.username", clickhouseContainer::getUsername);
            registry.add("spring.datasource.password", clickhouseContainer::getPassword);
            registry.add("spring.datasource.driver-class-name", clickhouseContainer::getDriverClassName);
        };
    }
}

우리가 ClickHouseContainer 빈을 생성할 때 ClickHouse 이미지의 최신 안정된 버전을 지정합니다.

이후 필요한 데이터 소스 속성을 구성하기 위해 DynamicPropertyRegistrar 빈을 정의합니다. 이를 통해 애플리케이션이 ClickHouse 데이터베이스 컨테이너에 연결될 수 있습니다.

올바른 연결 세부 정보를 구성하면 Spring Boot는 나중에 튜토리얼에서 사용할 JdbcTemplate 빈을 자동으로 생성합니다.

3.3. 개발 중 Testcontainers 사용하기

Testcontainers는 주로 통합 테스트에 사용되지만 로컬 개발 중에도 사용할 수 있습니다.

이를 위해, src/test/java 디렉토리에 별도의 메인 클래스를 생성합니다:

class TestApplication {

    public static void main(String[] args) {
        SpringApplication.from(Application::main)
          .with(TestcontainersConfiguration.class)
          .run(args);
    }
}

TestApplication 클래스를 생성하고, 그 안의 main() 메서드에서 TestcontainersConfiguration 클래스를 사용하여 애플리케이션을 실행합니다.

이 설정은 외부 서비스를 로컬에서 설정하고 관리하는 데 도움을 줍니다. 우리는 Spring Boot 애플리케이션을 실행하고 Testcontainers를 통해 시작된 외부 서비스에 연결할 수 있습니다.

4. CRUD 작업 수행하기

이제 로컬 환경이 설정되었으므로, JdbcTemplate 빈을 사용하여 authors 테이블과 상호작용해 보겠습니다:

Author author = Author.create("John Doe", "doe.john@baeldung.com");

jdbcTemplate.update(
    """
        INSERT INTO authors (id, name, email, created_at)
        VALUES (?, ?, ?, ?);
    """,
    author.id(),
    author.name(),
    author.email(),
    author.createdAt()
);

여기서 우리는 create() 메서드를 사용해 새로운 Author 인스턴스를 생성하고, 그런 다음 JdbcTemplateupdate() 메서드를 사용하여 authors 테이블에 삽입합니다.

author 레코드가 성공적으로 지속되었는지 검증하기 위해, id를 사용하여 읽기 쿼리를 실행해 보겠습니다:

List<Author> retrievedAuthors = jdbcTemplate.query(
    "SELECT * FROM authors WHERE id = ?",
    (ResultSet resultSet, int rowNum) -> new Author(
        UUID.fromString(resultSet.getString("id")),
        resultSet.getString("name"),
        resultSet.getString("email"),
        resultSet.getObject("created_at", LocalDateTime.class)
    ),
    author.id()
);

assertThat(retrievedAuthors)
  .hasSize(1)
  .first()
  .satisfies(retrievedAuthor -> {
      assertThat(retrievedAuthor.id()).isEqualTo(author.id());
      assertThat(retrievedAuthor.name()).isEqualTo(author.name());
      assertThat(retrievedAuthor.email()).isEqualTo(author.email());
      assertThat(retrievedAuthor.createdAt()).isNotNull();
  });

JdbcTemplatequery() 메서드를 사용하여 저장된 author 레코드를 id로 검색하고, 가져온 author가 이전에 저장한 것과 일치하는지 확인합니다.

시연을 위해, 우리는 저장 및 읽기 작업만 수행했습니다. 그러나 ClickHouse의 더 많은 문법과 연산자를 배우기 위해 SQL 참조를 사용할 수 있습니다.

5. 결론

이번 글에서는 ClickHouse 데이터베이스를 Spring Boot 애플리케이션에 통합하는 방법을 탐구했습니다.

우리는 Flyway 마이그레이션 스크립트를 사용해 데이터베이스 안에 authors 테이블을 생성했습니다. 그런 다음 Testcontainers를 사용해 ClickHouse 데이터베이스를 위한 임시 Docker 컨테이너를 시작하여 로컬 테스트 환경을 만들었습니다.

마지막으로, JdbcTemplate을 사용하여 authors 테이블에서 저장 및 읽기 작업을 수행했습니다.

항상 그렇듯 이 글에서 사용된 모든 코드 예제는 GitHub에서 확인할 수 있습니다.

원본 출처

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다