프로그래밍

[트러블 슈팅] 매년 바뀌는 전공 이수 기준, 어떻게 설계해야 깨지지 않을까?

d 0_0 b 2026. 1. 1. 14:27

1년 반 전 즈음 학과의 커리큘럼 페이지를 전담해서 구축한 적이 있다.

 

아무것도 모르는 상태로 구현하니, 굉장히 구린 페이지가 완성 됐는데 졸업 전 이걸 해결하고 졸업하고 싶어 친한 지인(ㅁㄱ님, ㅅㅇ님)께 부탁드려 갈아엎기로 했다.

 

 

 

전공 커리큘럼 페이지를 다시 만들면서 가장 많이 고민했던 질문은 이것이었다.
“매년 바뀌는 전공 이수 기준을, 어떻게 하면 구조적으로 깔끔하게 표현할 수 있을까?”

 

 

단순히 과목 목록을 보여주는 서비스라면 쉽다. (기존의 서비스)
하지만 내가 만들고 싶었던 것은:

  • 학번(년도) 기준으로 졸업 이수 표준을 보여주고
  • 학기(1-1 ~ 4-2)별로 과목을 배치하고
  • 각 과목이 전공필수(M)인지, 전공선택인지, 핵심(C)인지를 명확히 표시하고
  • 커리어 선택 시 관련 과목을 강조해주는 UI였다.

문제는 이 기준이 매년 바뀐다는 점이었다.

 

매번 학사서비스에 들어가서 내 학번 기준 졸업 기준을 찾아보거나 학과 사무실에 문의해야 하니, 추가적인 업무로 이루어진다는 불편함이 있다.

 

 


처음 떠올린 단순한 생각: “Subject에 year만 넣으면 되지 않을까?”

가장 처음 든 생각은 굉장히 단순했다.

“그냥 Subject 테이블에 year 컬럼 하나 추가하면 되는 거 아닌가?”

예를 들면 이런 식이다.

Subject
- id
- name
- semester
- credits
- requirementType (전필/전선)
- year

하지만 이 구조를 조금만 현실적으로 생각해보면 바로 문제가 드러난다.


왜 Subject.year 방식은 위험한가?

문제 상황 예시: 같은 과목, 다른 년도

“자료구조”라는 과목이 있다고 하자.

기준 년도학기이수구분

2024 2-1 전공선택
2025 1-2 전공필수

이걸 Subject.year로 표현하려면 결국 이렇게 된다.

Subject
- id=10, name="자료구조", year=2024, semester=2-1, requirementType=전선
- id=55, name="자료구조", year=2025, semester=1-2, requirementType=전필

즉, 과목 자체가 년도마다 복제된다.

 


복제의 후폭풍

과목이 복제되면 문제가 연쇄적으로 발생한다.

  • 선수과목 관계는 어느 자료구조를 가리켜야 할까?
  • 커리어 추천은 2024 자료구조? 2025 자료구조?
  • 트랙(마이크로전공)에 포함된 과목은 어떤 id를 써야 할까?

결국 모든 관계 테이블이 년도별 Subject 복제본을 기준으로 다시 연결되어야 한다.

이건 단순히 컬럼 하나 추가로 끝날 문제가 아니었다.
오히려 데이터 중복 + 관계 복잡도 폭발로 이어진다.

 

 


“바뀌는 건 과목이 아니라, 과목의 ‘역할’이다”

이 시점에서 관점을 바꿨다.

과목이 년도별로 바뀌는 게 아니다
년도별로 ‘과목의 위치와 역할’이 바뀐다

 

즉,

  • 과목명, 코드, 기본 설명 → 거의 안 바뀜
  • 어느 학기에 배치되는지
  • 전공필수인지 / 전공선택인지
  • 핵심 과목인지
  • 정렬 순서, 학점

이 값들이 년도(졸업 기준)에 따라 바뀐다.

그래서 이걸 분리하기로 했다.


 

 

설계 전환: Curriculum + CurriculumSubject

1. Subject: 과목 그 자체 (카탈로그)

Subject
- id
- code
- name
- description
- isOriginalLanguage
  • “자료구조”는 여기서 단 한 번만 존재
  • 선수과목/연계과목 같은 논리적 관계의 중심

2. Curriculum: 졸업 이수 기준 (년도 / 학번 기준)

Curriculum
- id
- year (예: 2025)
- name (예: "2025학번 졸업요건")
- isActive
  • 사용자가 선택하는 “년도” = 사실상 학번 기준
  • 매년 하나씩 추가, 보통은 이전 년도 복제 후 수정

3. CurriculumSubject: 년도 기준에서의 과목 역할 

CurriculumSubject
- curriculum_id
- subject_id
- semester (1-1 ~ 4-2)
- credits
- requirementType (전필/전선)
- isCore
- displayOrder

여기에 년도별로 바뀔 수 있는 모든 값을 몰아넣었다.


예시로 보면 확실해진다

“자료구조” 하나로 두 년도를 표현해보자

Subject
- id=10, name="자료구조"
Curriculum
- id=1, year=2024
- id=2, year=2025
CurriculumSubject
- curriculum_id=1, subject_id=10, semester=2-1, requirementType=전선, isCore=false
- curriculum_id=2, subject_id=10, semester=1-2, requirementType=전필, isCore=true

 과목은 하나
 년도별 차이는 CurriculumSubject row로만 표현
 관계(선수과목, 커리어 추천, 트랙)는 Subject 기준으로 그대로 유지


이 구조가 주는 장점

1) 년도별 졸업 기준 표현이 자연스럽다

  • “2025 기준 전필 과목”
  • “2024 기준 2-1 학기 표”

2) 데이터 중복이 없다

  • 과목은 한 번만 정의
  • 관계 테이블 재연결 필요 없음

3) 매년 개편 대응이 쉽다

  • Curriculum 복제
  • CurriculumSubject 일부 수정

4) UI 요구사항과 정확히 맞는다

  • 학기 탭
  • 전필(M) / 핵심(C) 뱃지
  • 커리어 선택 시 하이라이트

정리

처음엔 “year 하나만 추가하면 되지 않을까?”라고 생각했다.
하지만 요구사항을 졸업 기준, 학기 배치, 이수 구분 관점으로 재해석하면서 깨달았다.

 

 

커리큘럼 페이지에서 년도에 따라 바뀌는 건 과목이 아니라, 과목의 ‘역할’이다.

그래서 선택한 구조는:

  • Subject: 변하지 않는 과목
  • Curriculum: 년도(학번)별 졸업 기준
  • CurriculumSubject: 그 기준에서 과목이 어떤 역할을 하는지

이 분리가,
매년 바뀌는 전공 이수 기준을 가장 덜 아프게 감당할 수 있는 방법이라고 생각한다.