JPA를 사용하여 인덱스 (비 고유 키) 지정


100

email를 들어 JPA 주석을 사용하여 색인을 갖는 것과 같이 필드를 어떻게 정의합니까? email이 필드에는 하루에 문자 그대로 수백만 개의 쿼리가 있고 키가 없으면 약간 느리기 때문에 고유하지 않은 키가 필요합니다 .

@Entity
@Table(name="person", 
       uniqueConstraints=@UniqueConstraint(columnNames={"code", "uid"}))
public class Person {
    // Unique on code and uid
    public String code;
    public String uid;

    public String username;
    public String name;
    public String email;
}

최대 절전 모드 특정 주석을 보았지만 여전히 최대 절전 모드와 데이터 핵 사이를 결정하고 있으므로 공급 업체별 솔루션을 피하려고합니다.

최신 정보:

JPA 2.1부터이 작업을 수행 할 수 있습니다. 참조 : 이 위치에 @Index 주석이 허용되지 않습니다.


6
사람들은 JPA 2.1 함께 할 수있는 방법이 정말 있다는 것을 찾을 수 있도록 답을 업데이트 할 수 있다면 좋을 것
borjab

2
가장 찬성 된 답변을 받아들이지 않는 이유는 무엇입니까?
naXa

답변:


208

JPA 2.1을 사용하면 할 수 있습니다.

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;

@Entity
@Table(name = "region",
       indexes = {@Index(name = "my_index_name",  columnList="iso_code", unique = true),
                  @Index(name = "my_index_name2", columnList="name",     unique = false)})
public class Region{

    @Column(name = "iso_code", nullable = false)
    private String isoCode;

    @Column(name = "name", nullable = false)
    private String name;

} 

업데이트 : 두 개 이상의 열을 만들고 색인을 생성해야하는 경우 쉼표를 사용할 수 있습니다. 예를 들면 :

@Entity
@Table(name    = "company__activity", 
       indexes = {@Index(name = "i_company_activity", columnList = "activity_id,company_id")})
public class CompanyActivity{

그의 답변에 대해 Alvin에게 감사드립니다. (+1 투표). 그러나 나는 내가이 예 쉽게 당신의 인생을 만들 수 있습니다 희망 몇 가지를 찾기 위해 한
borjab

내가 찾던 바로 그 것-간단하고 깔끔한 코드는-전체를 설명 할뿐만 아니라. 감사합니다 +1.
DominikAngerer 2014

2
@borjab- @Index주석 내에서 @Table주석 을 사용하기위한 "공식"예제 또는 사양을 찾을 수있는 힌트를 주실 수 있습니까? JSR 338 에서 검색 했지만 거기에서 찾지 못했습니다. 귀하의 게시물은 나에게 매우 유용합니다.
JimHawkins

2
@Ulrich 정확히는 공식 documentatio하지만 오라클 블로그 blogs.oracle.com/arungupta/entry/jpa_2_1_schema_generation
borjab

@Column (unique = true) 열이 있으면 인덱스 목록에 병합됩니까 (unique도 인덱스이기 때문에)?
wkrueger

34

엄선 된 색인 주석 모음

= 사양 =

= ORM 프레임 워크 =

= Android 용 ORM =

= 기타 (분류하기 어려움) =

  • Realm -iOS / Android 용 대체 DB : Annotation io.realm.annotations.Index;
  • Empire-db- JDBC 기반의 가볍지 만 강력한 관계형 DB 추상화 계층입니다. 주석을 통한 스키마 정의가 없습니다.
  • Kotlin NoSQL (GitHub) -NoSQL 데이터베이스 (PoC) 작업을위한 반응적이고 유형이 안전한 DSL : ???
  • Slick -Scala를위한 반응성 기능적 관계형 매핑. 주석을 통한 스키마 정의가 없습니다.

그들 중 하나를 찾으십시오.


31

JPA 2.1 (마침내)은 인덱스와 외래 키에 대한 지원을 추가합니다! 자세한 내용은 이 블로그 를 참조하십시오. JPA 2.1은 Java EE 7의 일부입니다.

엣지에서 살고 싶다면 maven 저장소 (groupId : org.eclipse.persistence, artifactId : eclipselink, version : 2.5.0-SNAPSHOT) 에서 eclipselink의 최신 스냅 샷을 얻을 수 있습니다 . JPA 주석 (2.1을 지원하면 모든 공급자와 함께 작동해야 함)의 경우 artifactID : javax.persistence, version : 2.1.0-SNAPSHOT을 사용합니다.

출시 후까지 완료되지 않을 프로젝트에 사용하고 있으며 끔찍한 문제를 발견하지 못했습니다 (비록 너무 복잡한 작업은하지 않지만).

업데이트 (2013 년 9 월 26 일) : 현재 eclipselink의 릴리스 및 릴리스 후보 버전은 중앙 (메인) 저장소에서 사용할 수 있으므로 더 이상 Maven 프로젝트에서 eclipselink 저장소를 추가 할 필요가 없습니다. 최신 릴리스 버전은 2.5.0이지만 2.5.1-RC3도 있습니다. 2.5.0 릴리스의 문제로 인해 가능한 빨리 2.5.1로 전환 할 것입니다 (modelgen 항목이 작동하지 않음).


9

JPA 2.1에서는 다음을 수행해야합니다.

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.Table;

@Entity(name="TEST_PERSON")
@Table(
    name="TEST_PERSON", 
    indexes = {
       @Index(name = "PERSON_INDX_0", columnList = "age"),
       @Index(name = "PERSON_INDX_1", columnList = "fName"),
       @Index(name = "PERSON_INDX_1", columnList = "sName")  })
public class TestPerson {

    @Column(name = "age", nullable = false)
    private int age;

    @Column(name = "fName", nullable = false)
    private String firstName;

    @Column(name = "sName", nullable = false)
    private String secondName;

    @Id
    private long id;

    public TestPerson() {
    }
}

위의 예에서 TEST_PERSON 테이블에는 3 개의 인덱스가 있습니다.

  • 기본 키 ID의 고유 인덱스

  • AGE에 대한 색인

  • FNAME, SNAME의 복합 색인

참고 1 : 이름이 같은 두 개의 @Index 주석을 사용하여 복합 인덱스를 얻습니다.

참고 2 : fieldName이 아닌 columnList에 열 이름을 지정합니다.


5

표준화 된 방식으로 데이터베이스 색인을 지정할 수 있기를 원하지만 슬프게도 이것은 JPA 사양의 일부가 아닙니다 (아마도 DDL 생성 지원이 JPA 사양에 필요하지 않기 때문입니다. 그러한 기능).

따라서이를 위해 제공 업체별 확장에 의존해야합니다. Hibernate, OpenJPA 및 EclipseLink는 분명히 그러한 확장을 제공합니다. DataNucleus를 확인할 수는 없지만 인덱스 정의가 JDO의 일부이기 때문에 그렇다고 생각합니다.

색인 지원이 다음 버전의 사양에서 표준화되어 어떻게 든 다른 답변과 일치하지 않기를 바랍니다 .JPA에 그러한 것을 포함하지 않을 좋은 이유가 없습니다 (특히 데이터베이스가 항상 통제하에 있지 않기 때문에) 최적의 DDL 생성 지원을 위해.

그건 그렇고, JPA 2.0 사양을 다운로드하는 것이 좋습니다.


4

내가 아는 한, 인덱스를 지정하는 교차 JPA 공급자 방법은 없습니다. 그러나 언제든지 데이터베이스에서 직접 직접 만들 수 있으며 대부분의 데이터베이스는 쿼리 계획 중에 자동으로 선택합니다.


2
롤, 그것은 당신이 DBA의 일을하는 DBA가 있다고 가정합니다 (:
Jacob

3
"고유 한"방법이 있지만 색인을 만드는 방법은 없다는 것이 약간 이상합니다.
Jacob

7
@Jacob-응용 프로그램 수준에서 일부 필드가 고유한지 여부를 아는 것이 중요합니다. 반면 인덱스는 db 액세스를 최적화하기위한 것입니다. 열이 Java 계층에서 인덱스인지 여부를 알 필요가 없습니다 (내가 보는 한). 말했듯이 DBA는 특정 열이 혜택을받을 것 같으면 인덱스를 설정할 수 있습니다.
Java Drinker

1
@Jacob, 그것은 단순히 최적화 (보통 중요한 것이지만 여전히 최적화)이기 때문에 인덱스 지원이 없습니다. 필드 (또는 필드 집합)가 고유하거나 모델에 따라 다르며 정확성에 영향을 미치는 경우 OTOH. 또한 본격적인 200USD / Hr DBA가 필요하지 않으며 일반적으로 간단한 인덱스 생성 문으로도 충분합니다.
Tassos Bassoukos 2010 년


2

EclipseLink는 열에 대한 인덱스를 정의하기 위해 주석 (예 : @Index )을 제공했습니다 . 그 사용 의 예가 있습니다. 예제의 일부가 포함되어 있습니다 ...

firstName 및 lastName 필드는 함께 개별적으로 인덱싱됩니다.

@Entity
@Index(name="EMP_NAME_INDEX", columnNames={"F_NAME","L_NAME"})  // Columns indexed together
public class Employee{
    @Id
    private long id;

    @Index                      // F_NAME column indexed
    @Column(name="F_NAME")
    private String firstName;

    @Index                      // L_NAME column indexed
    @Column(name="L_NAME")
    private String lastName;
    ...
}



0

JPA 주석을 사용하는 것은 불가능합니다. 그리고 이것은 의미가 있습니다. UniqueConstraint가 비즈니스 규칙을 명확하게 정의하는 경우 인덱스는 검색 속도를 높이는 방법 일뿐입니다. 따라서 이것은 실제로 DBA에 의해 수행되어야합니다.


0

이 솔루션은 EclipseLink 2.5 용이며 작동합니다 (테스트 됨).

@Table(indexes = {@Index(columnList="mycol1"), @Index(columnList="mycol2")})
@Entity
public class myclass implements Serializable{
      private String mycol1;
      private String mycol2;
}

이것은 오름차순을 가정합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.