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 |