| 관련 SQL 개념
(1) Unique Key : 중복 데이터 저장을 방지하기 위한 제약조건
- 단일 칼럼 뿐 아니라, 복합 칼럼을 지정할 수도 있다.
- 아래와 같이 복합 키를 생성할 경우, DB 조회 속도를 향상시킬 수 있다.
-- MySQL 기준
create table member(
email varchar(50),
name varchar(255),
unique key member_uk_email (email, name)
)
- 중복 데이터 저장을 막기 위한 방법으로 아래 두가지를 사용할 수 있다.
* 단순 insert into 문의 경우 에러를 발생하지만, 아래 두 가지는 에러를 발생시키지 않는다.
INSERT IGNORE | unique key가 걸린 칼럼에 중복 데이터가 이미 있는 경우 삽입 X |
INSERT ~~~ ON DUPLICATE KEY UPDATE | unique key가 걸린 칼럼에 중복 데이터가 이미 있는 경우 업데이트 |
insert ignore into member values ('jamie@gmail.com','JAMIE');
-- 0 raw affected (error x)
insert ignore into member values ('jamie@gmail.com','JAMIE');
insert ignore into member values ('jamie@gmail.com','JAMIE');
insert ignore into member values
on duplicate key update ('jamie@gmail.com','JAMIE');
-- 2 raw affected (error x)
insert ignore into member values
on duplicate key update ('jamie@gmail.com','JAMIE');
insert ignore into member values
on duplicate key update ('jamie@gmail.com','JAMIE');
(2) Index : 추가적인 쓰기 작업과 저장공간을 활용해 DB table의 검색 속도를 향상시키기 위한 자료구조
- Index는 다양한 자료구조를 통해 만들 수 있다.(ex. Hashtable)
- 가장 많이 사용되는 자료구조는, B+Tree 구조이다.
* B+Tree 구조란, DB인덱스를 위해 자식노드가 2개 이상인 B-Tree를 개선시킨 자료구조를 말한다.
* 일반적으로 조회시 O(logN)의 시간을 가진다.
- Index는 아래처럼 두 가지로 종류를 나눌 수 있다.
cluster index | primary key를 통해 인덱스를 설정 (ex. 처음부터 정렬된 영어사전) |
보조 index | unique key를 통해 인덱스를 설정 (ex. 책 뒤의 찾아보기) |
* 참고 )
cluster와 보조index를 같이 쓸 경우 INDEX로 입력할 수 있지만, 보조 index만 쓸 경우 UNIQUE INDEX를 써야한다.
* 자세한 내용 : https://enterkey.tistory.com/417
- Index는 아래와 같이 테이블을 생성할 때 만들 수도 있고, 별도로 alter문으로 제약조건을 붙일 수도 있다.
create table member(
id bigint primary key, -- cluster key
email varchar(50),
name varchar(255),
unique key member_uk_email (email, name),
INDEX member_idx (id, email)
)
- Index의 장단점
장점 | - Index를 사용하면 조회 속도를 향상시킬 수 있어, DB 서버의 부하를 줄일 수 있다. |
단점 | - 하지만 추가 저장공간을 사용해야하고, - insert, update, delete 같은 데이터 변경 쿼리가 자주 사용되는 경우에 인덱스를 쓰면 paging이 빈번해져 성능이 악화될 수 있다.(== 조회 보다 db 변동이 많은 경우 불리) - 추가적으로 cardinality가 낮은 경우(= 중복 데이터가 많은 경우), 인덱스를 사용하는 것이 비효율적일 수 있다. |
* Selectivility : 데이터 집합에서 특정 값을 얼마나 잘 골라낼 수 있는지에 대한 지표
>> Selectivility = Cardinality / Total number of Records
>> Selectivility = 1 <-- 모든 레코드가 유니크하다.
* cardinality : 특정 데이터 집합의 유니크(Unique)한 레코드의 개수
- Index를 설계할 때 알아둘 점
[효율적인 인덱스 설계 ] - Where절에 사용되는 열 - Select절에 자주 등장하는 칼럼을 잘 조합해 Index로 만들면 조회 시간을 줄일 수 있다. - JOIN절에 자주 사용되는 열 - Order by 절에 사용되는 열은 클러스터 인덱스가 유리하다. [금지해야할 인덱스 설계] - 대용량 데이터가 자주 입력되는 경우 primary보다 unique를 설정한다. - 데이터 중복도가 높은 열은 인덱스 효과가 없다. (ex. 성별) - 자주 사용되지 않으면 성능 저하를 초래할 수 있다. |
| 스프링에서 중복 데이터 저장을 방지하기
1. Primary key 설정하기
- 사용할 칼럼에 @Id 를 넣어준다.
- @GeneratedValue 를 통해 auto_increment가 가능하게 한다.
* auto : 자동선택, identity : db identity 칼럼 사용, sequence : 시퀀스를 쓰는 db vendor에서 사용
2. Unique Key & Index 설정
- @Entity 클래스에서, @Table(uniqueConstraints = {}) 를 통해 unique 제약조건을 설정한다.
- Unique key를 아래와 같이 설정하게 되면 해당 키를 곧 인덱스로 인식한다.
@Entity(name = "DIVIDEND")
@NoArgsConstructor
@Getter
@ToString
@Table( // 복합 unique키 설정 (중복 저장 X)
uniqueConstraints = {
@UniqueConstraint(
columnNames = {"companyId", "date"}
)
}
)
public class DividendEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long companyId;
private LocalDateTime date;
private String dividend;
public DividendEntity(Long companyId, Dividend dividend) {
this.companyId = companyId;
this.date = dividend.getDate();
this.dividend = dividend.getDividend();
}
}
[ 참고 및 출처]
* 부트캠프 수업 내용 정리
* 인덱스 개념 참조 : https://mangkyu.tistory.com/96
* Cardinality와 Selectivility : https://soft.plusblog.co.kr/87
* 유니크 키를 통한 중복데이터 관리방법 https://umanking.github.io/2021/07/05/mysql-duplicate-record/
'Framework > Orm&Mapper' 카테고리의 다른 글
[JPA] CascadeType : 상위 -> 하위 엔터티 전파 타입 (0) | 2022.11.28 |
---|---|
[JPA] Lazy Loading 개념 (0) | 2022.11.11 |
[Transaction] Transaction에 대한 이해 (& 스프링의 @Transactionl) (1) | 2022.10.25 |
[JPA] 인텔리J에서 JPA Entity 기반 ERD 그리기 (0) | 2022.10.19 |
[JPA] repository.save()의 반환값이 안 들어올 때 (0) | 2022.10.19 |