본문 바로가기
CS공부/SQL

DB - key, 관계매핑, fetch

by 티코딩 2024. 1. 30.

Spring 을 사용하며 항상 헷갈렸던 개념이어서 한번은 정리의 필요성을 느끼고 정리해보려고 한다.

DB에서 Key는 무슨 역할을 할까?

 

ㅇ Key의 역할

- 키는 각 레코드를 고유하게 식별하는 역할을 함. 중복된 레코드를 방지할 수 있다.

- 키를 사용하면 DB에서 레코드를 신속하게 찾고 조작할 수 있음. 효율적으로 검색할 수 있고 정렬할 수도 있다.

- 데이터의 무결성을 보장한다. primary key는 각 레코드를 고유하게 식별해 데이터의 무결성을 유지하는데 역할을 한다. 또, 외래키를 사용해 다른 테이블 과의 관계를 정의하고 무결성 제약 조건을 적용 할 수 있다.

- 테이블 간의 관계를 정의. 외래키는 한 테이블의 레코드가 다른 테이블의 특정 레코드와 관련되어 있음을 나타낸다.

ㅇ Key의 종류

ㅁ 기본키(Primary Key)

테이블에서 각 행을 고유하게 식별하는데 사용됨. 주로 숫자 또는 문자열로 구성됨. 예를 들어 member테이블에 memerId가 기본키가 된다. 

ㅁ 외래키(Foreign Key)

한 테이블의 열이 다른 테이블의 기본 키와 관련된 경우에 사용됨. 두 테이블간의 관계를 설정할 수 있다. 예를 들어 Order테이블에서 각 주문의 memberId가 외래키로 사용될 수 있다.

ㅁ 고유키(Unique Key)

테이블의 각 행을 식별하는 데 사용되지만, 기본 키 처럼 자동으로 생성되지 않음. 중복값이 없도록 각 열에 대한 유일한 값을 가짐. 예를 들어 이메일 정보가 고유키로 사용된다.

ㅁ 보조키(Secondary Key)

테이블의 검색 속도를 향상시키기 위해 사용됨. 테이블에서 자주 검색되는 열에 대한 인덱스를 생성해 보조키로 사용할 수 있다. 예를들어 User 테이블에서 last name 열에 대한 인덱스가 생성 될 수 있다.

 

ㅇ 스프링에서의 Key, N:1

ㅁ User entity

@Entity
@Table(name = "users")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String username;
    private String email;
    // 다른 필드들...
    
    // Getters and setters
}

 

ㅁ Post Entity

@Entity
@Table(name = "posts")
public class Post {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String title;
    private String content;
    // 다른 필드들...
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
    
    // Getters and setters
}

이렇게 설정했다고 가정하자.

User 엔티티에서 사용자 정보를 나타내고 id라는 고유의 기본 키(Primary Key)를 갖는다. Post 엔티티에서도 게시물 정보를 나타내고, id라는 고유의 기본 키를 갖는다. 그리고 user_id라는 이름의 외래키를 지정했다. Post 엔티티는 User 엔티티와 다대일 관계를 맺고있다. 한 User에 대해 여러개의 Post가 있을 수 있지만, 한 Post는 하나의 User에만 속한다. 고로 Post(N), User(1) 이된다.

 

ㅇ 스프링에서 N:N

ㅁ Book Entity

@Entity
@Table(name = "books")
public class Book {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String title;
    private String isbn;
    // 다른 필드들...
    
    @ManyToMany(mappedBy = "books")
    private Set<Author> authors = new HashSet<>();
    
    // Getters and setters
}

 

ㅁ Author Entity

@Entity
@Table(name = "authors")
public class Author {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
    // 다른 필드들...
    
    @ManyToMany
    @JoinTable(
        name = "author_book",
        joinColumns = @JoinColumn(name = "author_id"),
        inverseJoinColumns = @JoinColumn(name = "book_id"))
    private Set<Book> books = new HashSet<>();
    
    // Getters and setters
}

각 Book은 여러명의 Author과 관계를 맺을 수 있음. 각 Author도 여러Book과 관계를 맺을 수 있다. @ManyToMany를 쓸때 @JoinTable은 하나의 엔티티에서만 쓰면 된다. 양쪽 엔티티 사이의 연결 테이블을 지정하기만 하면 된다.@JoinTable을 안쓴 테이블에선 maapedBy 속성만 사용하여 매핑된 엔티티를 참조하기만 하면 된다.

 

ㅇ 스프링에서 1:1

ㅁ User Entity

@Entity
@Table(name = "users")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String username;
    private String email;
    // 다른 필드들...
    
    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
    private Profile profile;
    
    // Getters and setters
}

ㅁ Profile Entity

@Entity
@Table(name = "profiles")
public class Profile {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String fullName;
    private String bio;
    // 다른 필드들...
    
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", unique = true)
    private User user;
    
    // Getters and setters
}

한 유저는 하나의 프로필을 가질 수 있다. 그리고 각 프로필은 하나의 유저에게 연결된다.

 

ㅇ FetchType

JPA에서 관계형 매핑 어노테이션에서 사용됨.

ㅁ EAGER(즉시 로딩)

연관된 엔티티를 즉시 로딩해 함께 가져온다. 관계를 설정한 엔티티를 조회할 때, 연관된 엔티티도 즉시 로딩되어 메모리에 로드 됨. 연관된 엔티티가 많을 경우 성능 문제가 발생할 수 있다. 

ㅁ LAZY(지연 로딩)

연관된 엔티티를 필요할 때까지 로딩을 지연시킨다. 필요할때가지 로딩되지않고 실제로 연관된 엔티티에 접근할때 로딩된다.

EAGER보다 효율적으로 메모리를 관리할 수 있으며, 성능향상에 도움됨.

ㅁ DEFAULT(기본 설정)

기본적으로 LAZY가 적용됨. 연관된 엔티티를 즉시 가져오도록 강제할 수도 있음. 

 

 

'CS공부 > SQL' 카테고리의 다른 글

테이블 결합, JOIN, UNION  (0) 2024.01.23
ORDER BY절, 서브쿼리  (1) 2024.01.22
GROUP BY절, HAVING절  (0) 2024.01.19
CASE문, WHERE절  (0) 2024.01.16
SELECT절-숫자함수, 날짜함수, 순위함수  (0) 2024.01.12