Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[10주차] 임현우 학습 PR 제출합니다 #58

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions week10/10주차.md

This file was deleted.

32 changes: 32 additions & 0 deletions week10/임현우.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 10주차 학습 PR
## Indexing이란?
### Index란
- Index란 데이터베이스에서 테이블에 1개 이상의 컬럼을 사용하여 인덱스 값을 새긴 것이다. 그리고 이 Index를 사용하여 특정 데이터를 골라내는 것을 Indexing이라고 한다. 이 자료 구조를 통해 검색의 속도를 높일 수 있다.
### B-Tree Index
- B-Tree Index 구조는 N개의 자식을 가지는 트리 구조로 이러한 구조는 좌우 자식 간의 균형이 맞지 않을 시 효율이 떨어지기 때문에 Balanced Tree라는 이름을 붙이고 균형을 조절하여 사용한다. 이 구조의 최상단에는 하나의 노드만이 존재하며 이 노드는 Root 노드라고 부른다. 그리고 중간 노드는 Branch 노드, 최하단 노드는 Leaf 노드라고 한다. B-Tree의 장점은 어떤 값에 대해서도 같은 시간(O(logN))을 사용한다는 점이다.
### Clustered Index, Non-Clustered Index
- Clustered Index는 테이블의 실제 데이터를 정렬하게 한다. 이 때 Clustered Index는 테이블당 하나만 존재한다. 각각 1부터 5까지의 Clustered Index 값을 가진 데이터들이 한 테이블 내에 있다고 가정해보자. 이 때 만일 새로운 데이터를 Clustered Index를 2로 설정하여 추가한다면 기존의 2부터 5의 데이터들은 각각 1씩 밀려난 값을 가지게 된다. 이렇듯 항상 Clustered Index를 기준으로 정렬되기 때문에 검색 속도는 뛰어나지만 유지보수 시 비용이 커진다는 단점이 있다.
- Non-Clustered Index는 그와 반대로 데이터가 물리적으로 정렬되지 않고 인덱스만이 정렬된다. 인덱스는 데이터의 물리적 장소를 가리키는 포인터와 매핑된다. 그리고 포인터가 가리키는 물리 주소로부터 데이터를 찾는 구조이다. 때문에 새로운 데이터가 중간에 추가되더라도 포인터만 변경하면 되기 때문에 유지보수의 비용이 적지만 검색 시 한 단계를 더 거치는 만큼 속도가 상대적으로 느리다는 단점이 있다. 하나의 테이블에서 여러 개의 인덱스를 가질 수 있다.
### Secondary Index
- Secondary Index는 Primary Index가 아닌 또 다른 인덱스이다. Secondary Index는 순서를 가지지 않으며 실제 데이터의 물리적 위치와 해당 열의 값을 매핑한다. Secondary Index를 사용하면 해당 열에 대한 검색 속도를 높일 수 있다. 하지만 유지보수 시 오버헤드가 커지게 된다. Non-Clustered Index와 비슷해 보이지만 엄연히 다르다.

## DB의 Relationship(1:1, 1:m, n:m)
- 1:1은 서로 다른 테이블의 레코드들이 서로 1:1로 매핑되는 관계이다. 1:M은 하나의 레코드가 여러 개의 레코드와 매핑되는 관계이다. A와 B가 1:M의 관계라면 A는 여러 개의 B를 가질 수 있지만 B가 여러 개의 A를 가지는 것은 불가능하다. 마지막으로 M:N은 여러 개의 레코드끼리 매핑되는 관계이다. A가 여러 개의 B를 가지고 마찬가지로 B 또한 여러 개의 A를 가지는 것이다. 이 경우 Join 테이블이라고 부르는 또 다른 테이블을 통해 두 테이블 간의 관계를 정리한다. 이 경우 데이터의 크기도 커지며 데이터 수정 시 두 테이블 모두에서 수정의 확인을 해야 하는 등 비용이 커지게 된다.

## JPA 엔티티의 생명 주기
### 엔티티의 상태
- JPA의 엔티티는 크게 4 종류의 상태가 있다. 첫번째는 비영속 상태로 순수한 객체의 상태이다. 이 때는 영속성 컨텍스트와 관련이 없다. 두번째는 영속 상태로 영속성 컨텍스트에 저장되어 관리되는 상태이다. 세번째는 준영속으로 영속성 컨텍스트에 저장되었다가 분리된 상태이다. 네번째는 삭제로 영속성 컨텍스트와 데이터베이스에서 삭제된 상태이다. 엔티티는 비영속 상태로 생성된 이후 영속 상태가 되고 영속상태와 준영속상태를 오가다가 삭제된다. 비영속 상태와 준영속 상태는 엇비슷해 보이나 준영속 상태는 영속화 과정을 거쳤기 때문에 식별자를 가지고 있다. 때문에 영속화 과정에 차이가 생기게 된다.
### 엔티티의 상태 변경
- Persist는 비영속 상태의 엔티티가 영속화되는 과정이다. Persist 이후 바로 DB에 저장되는 것은 아니고 이후 트랜잭션이 커밋되어야 영속성 컨텍스트 내부의 정보가 DB에 전달된다.
- 영속 상태의 엔티티가 준영속 상태가 되는 과정은 크게 3가지로 나누어진다. 첫번째는 detach이다. Detach는 특정 엔티티를 준영속 상태로 전환한다. 두번째는 clear이다. Clear는 영속성 컨텍스트를 초기화하여 영속 상태의 모든 엔티티를 준영속 상태로 전환한다. 세번째는 close이다. Clear와 마찬가지로 영속성 컨텍스트의 모든 엔티티를 준영속 상태로 전환하지만 이 경우 영속성 컨텍스트를 초기화하는 것이 아닌 종료하는 것이다. 준영속 상태의 엔티티를 다시 영속 상태로 전환하는 과정은 merge라고 한다.
- 영속 상태의 엔티티를 삭제하는 과정은 remove라고 한다. 이 경우에도 persist와 마찬가지로 트랜잭션이 커밋되어야 DB의 엔티티가 삭제된다.

## @Id, @ GeneratedValue
- 식별자는 Entity가 영속 상태가 되기 위해서는 필수적이다. 이 식별자를 부여하기 위한 방법으로는 크게 두 가지 방법이 있다. 첫번째는 직접 할당이다 말 그대로 애플리케이션에서 직접 식별자를 할당해주는 것이다. 두번째는 자동 생성이다. 이 방식은 대리 키를 사용하는 방식이다. 크게 IDENTIY, SEQUENCE, TABLE로 나눌 수 있다.
### 직접 할당 방식
- 직접 할당 방식을 사용 시 Entity의 Key Column에 @Id를 적용하여 사용 가능하다. @Id를 적용할 수 있는 자바 Type들로는 Primitive Type 형(int, double, long ...), Java Wrapper 형, String, java.util.Date, java.sql.Date, java.math.BigDecimal, java.math.BigInteger이 있다. 애플리케이션에서 Entity의 Key Column 값을 직접 할당한다. 이후 persist 과정을 통해 영속화한다.
### 자동 생성 방식
- 자동 생성 방식을 사용 시 Entity의 Key Column에 @Id와 @GeneratedValue를 적용하여 사용 가능하다. 이 때 @ GeneratedValue의 뒤에 (strategy = GenerationType.방법)을 통해 생성 방법을 정할 수 있다. 만일 방법을 정하지 않는다면 기본 설정 값인 AUTO로 생성된다. AUTO는 각 데이터베이스에 따라 자동으로 생성된다.
- IDENTITY는 기본 키의 생성을 데이터베이스에 위임하는 것이다. 식별자의 값을 애플리케이션에서 할당하지 않고 데이터베이스에서 자동으로 할당하는 방식이다. JPA는 보통 트랜잭션의 Commit 시점에서 할당한다. 이 방식은 데이터베이스에 값이 들어간 이후에 식별자 값을 알 수 있다. 때문에 영속성 컨텍스트의 1차 캐시에 필요한 ID 값을 얻기 위해 persist 직후 DB에 INSERT 쿼리를 날려 식별자를 조회한다. 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용된다.
- SEQUENCE는 데이터베이스의 시퀀스 오브젝트를 사용하는 방법이다. 시퀀스 오브젝트는 DB 내의 객체로 자동으로 번호를 생성하는 역할을 한다. Persist 호출할 때 먼저 시퀀스 오브젝트를 통해 식별자를 조회하고 조회한 식별자를 Entity에 할당하는 방식이다. 그 이후 Entity를 영속성 컨텍스트에 저장한다. 주로 Oracle, PostgreSQL, DB2, H2에서 사용된다.
- TABLE은 키 생성만을 위한 전용 테이블을 하나 만들고 데이터베이스 시퀀스를 흉내내는 방법이다. 때문에 테이블의 생성이 선행되어야 한다. 테이블을 사용하기 때문에 모든 데이터베이스에서 사용이 가능하다. SEQUENCE 전략보다 DB와 한 번 더 통신한다는 단점이 있다.