📢 스프링부트에서 인덱스키와 복합키를 어떻게 사용할 수 있는지 알아보자
인덱스는 책의 색인과 같은 역할을 한다.
데이터베이스 테이블에 있는 레코드를 빠르게 찾아낼 수 있도록 돕는 구조이다.
특정 컬럼(또는 컬럼들) 위에 인덱스를 생성함으로써, 해당 컬럼의 값으로 레코드를 검색할 때 데이터베이스가 전체 테이블을 스캔하지 않고도 해당 레코드를 찾아낼 수 있다.
이렇게 인덱스로 설정된 필드(또는 필드들)의 값은 '인덱스키'라고 부른다.
복합키는 두 개 이상의 컬럼을 결합하여 하나의 유니크한 키, 즉 기본키로 사용하는 것을 말한다.
예를 들어, '주문' 테이블에서 '사용자 ID'와 '상품 ID'가 각각 단독으로는 기본키로 사용될 수 없지만, 이 둘을 결합하면 주문 내역을 유일하게 식별할 수 있으므로 복합키로 사용된다.
즉, 인덱스키는 데이터 검색 성능 최적화를 위해 사용되며, 복합키는 여러 필드를 조합하여 레코드를 유일하게 식별하기 위해 사용된다.
스프링 부트에서 JPA를 사용하여 복합키를 사용하는 방법은 크게 두 가지다.
하나는 @IdClass
를 이용한 방법이고, 다른 하나는 @EmbeddedId
와 @Embeddable
을 이용한 방법이다.
먼저, 복합키 클래스
를 생성한다. 해당 클래스에는 equals()와 hashCode() 메서드가 반드시 구현되어야 한다.
public class OrderProductId implements Serializable {
private Long orderId;
private Long productId;
// getters, setters
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrderProductId that = (OrderProductId) o;
return Objects.equals(orderId, that.orderId) &&
Objects.equals(productId, that.productId);
}
@Override
public int hashCode() {
return Objects.hash(orderId, productId);
}
}
그리고 엔티티 클래스에서 @IdClass 어노테이션을 사용한다.
@Entity
@IdClass(OrderProductId.class)
public class OrderProduct {
@Id
private Long orderId;
@Id
private Long productId;
// other fields, getters and setters
}
복합 키 클래스에서는 아래처럼 @Embeddable 어노테이션을 사용한다.
@Embeddable
public class OrderProductId implements Serializable {
private Long orderId;
private Long productId;
// getters and setters
// equals and hashcode methods
}
엔터티 클래스에서는 아래처럼 @EmbeddedId 어노테이션을 사용한다.
@Entity
public class OrderProduct {
@EmbeddedId
private OrderProductId id;
// other fields
}
스프링 부트에서 JPA를 사용하여 인덱스를 정의하는 방법은 @Table
어노테이션과 함께 @Index
어노테이션을 사용하는 것이다.
이는 엔터티 클래스에 적용되며, 데이터베이스 테이블 생성 시 인덱스를 생성한다.
다음은 예시 코드이다:
@Entity
@Table(name = "users",
indexes = {@Index(name = "index_user_name", columnList="name", unique = true)})
public class User {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
@Column(name = "name")
private String name;
// other fields, getters and setters
}
위 코드에서 @Table 어노테이션 내부에 indexes 속성을 사용하여 인덱스를 정의하였다.
@Index 어노테이션이 인덱스 이름(name)과 컬럼 목록(columnList)을 지정하고 있다. unique 속성으로 유일성 여부도 지정할 수 있다.
참고로 이 방식은 JPA가 제공하는 DDL(Data Definition Language) 기능을 활용한 것으로, 실제 운영 환경에서는 데이터베이스 마이그레이션 도구(예: Flyway, Liquibase 등)를 사용하여 별도의 SQL 스크립트로 관리하는 것을 권장한다.