정규화는 데이터의 중복을 줄이고 데이터 무결성을 유지하기 위해 테이블을 체계적으로 분해하는 과정
목적
but, 테이블이 많이 분리되면서 조인이 많이 필요해져 쿼리가 복잡해질 수 있다. 또한 데이터 조회 시 조인 연산이 많아지면 성능이 저하될 수 있음. 정규화를 위해서는 신중한 설꼐와 분석이 필요.
비정규화된 테이블:
학생ID | 학생이름 | 과목
1 | 홍길동 | 수학, 영어
학생ID | 학생이름 | 과목
1 | 홍길동 | 수학
1 | 홍길동 | 영어
비정규화된 테이블:
주문ID | 상품ID | 주문일자 | 상품명
1 | 101 | 2024-01-01 | 노트북
주문 테이블:
주문ID | 상품ID | 주문일자
상품 테이블:
상품ID | 상품명
비정규화된 테이블:
학생ID | 학생이름 | 학과ID | 학과명
1 | 홍길동 | D01 | 컴퓨터공학
학생 테이블:
학생ID | 학생이름 | 학과ID
학과 테이블:
학과ID | 학과명
신입이나 취업 준비 중인 Java, Spring 백엔드 개발자 입장에서 정규화(Normalization)와 관련하여 실습할 수 있는 내용은 데이터베이스 설계와 데이터 처리 실습을 중심으로 진행할 수 있습니다. 실습을 통해 데이터베이스 설계 역량과 SQL 작성 능력을 키울 수 있으며, Spring과 연계하여 백엔드 개발 실무에 적용할 수도 있습니다.
Step 1: 비정규화된 데이터 세트를 준비합니다.
예: 학생, 강의, 수강 정보가 포함된 테이블을 비정규화된 상태로 설정
CREATE TABLE StudentCourses (
student_id INT,
student_name VARCHAR(100),
course_name VARCHAR(100),
professor_name VARCHAR(100),
course_time VARCHAR(100)
);
INSERT INTO StudentCourses VALUES
(1, '홍길동', '자바 기초', '이교수', '월요일 10시'),
(2, '김철수', '데이터베이스', '박교수', '화요일 2시'),
(1, '홍길동', '데이터베이스', '박교수', '화요일 2시');
Step 2: 1NF, 2NF, 3NF 과정을 적용하여 테이블을 분리합니다.
Step 3: SQL을 통해 분리된 테이블에서 데이터를 삽입/조회합니다.
정규화된 데이터베이스 설계
학생, 강의, 수강 테이블을 사용해 MySQL 또는 H2 데이터베이스에 구축합니다.Spring JPA 엔티티 생성
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "student")
private List<CourseRegistration> registrations;
}
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String professor;
@OneToMany(mappedBy = "course")
private List<CourseRegistration> registrations;
}
@Entity
public class CourseRegistration {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "student_id")
private Student student;
@ManyToOne
@JoinColumn(name = "course_id")
private Course course;
}
Repository와 서비스 구현
Repository를 통해 학생, 강의, 수강 정보를 CRUD 할 수 있도록 구현합니다.public interface StudentRepository extends JpaRepository<Student, Long> {}
public interface CourseRepository extends JpaRepository<Course, Long> {}
public interface CourseRegistrationRepository extends JpaRepository<CourseRegistration, Long> {}
RestController로 API 구현
@RestController
@RequestMapping("/students")
public class StudentController {
private final StudentRepository studentRepository;
@PostMapping
public ResponseEntity<Student> createStudent(@RequestBody Student student) {
return ResponseEntity.ok(studentRepository.save(student));
}
@GetMapping("/{id}")
public ResponseEntity<Student> getStudent(@PathVariable Long id) {
return ResponseEntity.ok(studentRepository.findById(id).orElseThrow());
}
}
테스트 및 검증
비정규화 테이블 설계
정규화 테이블과 성능 비교
Faker 라이브러리를 사용하여 대량의 테스트 데이터를 생성합니다.이러한 실습을 통해 정규화된 데이터 설계와 실무 적용 능력을 동시에 키울 수 있습니다!