요즘 저는 abcdedu 라는 교육 플랫폼 웹 서비스를 개발하며 정신 없는 나날을 보내고 있습니다.
여느 기능 보다 수업을 듣고 나서 남기는 설문 기능을 구현하며 많은 고민을 했습니다. 특히 DB와 관련된 부분을 이야기하고자 합니다.
1. 설문 기능은 어떻게 구성될까요?
설문 기능은 설문, 질문, 질문의 선택지, 응답으로 이루어진 거대한 개념이라고 생각했습니다.
각 기능을 분리해서 생각하여 테이블 또한 각각 구성하기로 했습니다.
개별적으로 설계함으로써 관리자가 언제든 설문에 대한 내용을 유연하게 수정할 수 있도록 각각의 기능을 분리하고자 했습니다.
기능 흐름)
- '2024 강의 만족도 조사' 라는 하나의 설문을 만듭니다.
- 해당 설문은 여러 개의 질문으로 구성됩니다.
- 질문은 설문 id를 외래키로 가져 어느 설문에 속하는 지 구분합니다.
- 질문 중 객관식은 선택지를 만들어 줍니다.
- 선택지는 질문 id를 외래키로 가져 어느 질문에 속하는 지 구분합니다.
- 응답자는 설문에 속한 질문에 대해 응답을 생성합니다.
- 질문이 필수 답변 속성이 false 라면 응답이 없을 수 있습니다.
- 응답은 설문 id를 외래키로 가져 어느 설문에 대한 응답인지 구분합니다.
- 한 설문에 대한 유저의 중복 설문이 가능합니다. ( 사용자 요청 )
2. DB 설계는 어떻게 했나요?
연결선을 중점으로 캡쳐했습니다.
테이블을 잇는 분홍색 선이 연결선으로 테이블간 관계를 내포하고 있습니다.
테이블 관계는 여러 기준으로 구분할 수 있습니다. 저는 그 에 식별/비식별 관계에 대해 고민했습니다.
식별/비식별 관계
이론적으로 생각해봅니다.
- 식별 관계
- 테이블의 기본키 or 유니크키가 연관 테이블의 기본키로 사용되는 관계
- 연관 테이블의 키가 자신의 기본키에 포함되기 때문에 연관 테이블에 데이터가 존재해야 해당 테이블에 데이터를 생성할 수 있습니다.
- 비식별 관계
- 연관 테이블의 기본키 or 유니크키를 외래 키로 사용하는 관계
- 연관 테이블에 데이터에 상관 없이 독립적으로 생성할 수 있습니다.
이렇게 이론적으로만 생각하니 어떤 관계를 사용해야 할 지 어떤 장점이 있는건지 알 수 없었습니다.
그래서 실무에선 어떤 관계가 더 선호되는지, 고려하는 점은 어떤게 있는지 살펴보았습니다.
결론부터 말하자면 성능 최적화가 중요한 시스템 (분산 아키텍처, 로그 데이터 관리) 에선 비식별 관계 사용을 지향하며 마이크로 서비스 환
경에서도 비식별 관계가 일반적이라고 합니다. (from Chat GPT)
하지만 관계형 데이터베이스를 사용하는 환경에서는 데이터 무결성 보장을 위해 식별관계를 사용하길 권장하고 있습니다.
그렇다면 식별/비식별 관계를 지정하는 것이 왜 성능과 데이터 무결성 보장과 관련 되는걸까요?
성능, 데이터 무결성, 확장성을 고려한 테이블 관계
식별 관계는 연관 관계에 있는 테이블의 기본 키를 외래키로 가져와 연관 반대편의 테이블의 기본키로 등록합니다.
기본키로 등록한다는 것은 테이블에 제약조건을 추가하는 것 입니다. 기본키로 등록된 필드는 null 값이여서도, 중복 되어서도 안되기 때문입니다.
이런 제약조건을 확인하기 위해 추가적인 액션이 이루어 집니다. 삽입이나 삭제 작업 시 외래 키로 참조된 데이터를 항상 확인해야 하기 때문입니다. 따라서 식별관계는 비식별관계에 비해 성능적으로 떨어집니다.
하지만 기본키로 등록되어 null 값이 들어올 수 없게 DB 계층에서 제약조건을 통해 점검함으로써 정합성을 높일 수 있습니다. 기본키로 등록된 외래키가 null일 수 없으니 연관된 테이블에 해당 데이터가 꼭 있을 것을 강제할 수 있기 때문입니다.
따라서 성능과 데이터 무결성 간의 관계를 잘 비교해보며 선택을 해야 하는 것입니다. 여기에 더해 확장성도 고려해야 합니다.
식별관계는 앞서 말했듯 제약 조건이 추가됩니다. 따라서 복잡한 비즈니스 로직이 필요한 경우나 요구사항이 바뀌는 경우 해당 조건을 다 고려한 프로그래밍을 해야 합니다.
그래서 어떻게 결정했나요?
제가 만들고 있는 시스템은 초기 단계이고 구현중에도 개발 계획이 종종 변경되고 있습니다. 변경사항에 최대한 유연하게 반응할 수 있는 것이 중요합니다.
따라서 기본적으로는 비식별관계로 정의 하되, 연관관계가 높고 스키마의 변경 가능성이 현저히 적은 관계는 식별관계로 정의하기로 했습니다.
아직까진 변경에 영향을 주는 식별관계를 정의할만큼 정합성이 중요한 관계는 없어서 모든 관계를 비식별 관계로 정의 중입니다.
다음으로
이번 포스트에는 abcdedu의 설문 기능을 개발하며 고민했던 점중 데이터의 식별/비식별 관계에 대한 내용을 얘기했습니다.
다음 포스트에서는 DB 카디널리티와 JPA 매핑에 대한 얘기로 찾아 뵙겠습니다.
오늘도 글 읽어주셔서 감사합니다.
제안이나 수정 사항 있으면 언제든 말씀주세요. :-)
'Programming > spring&java system' 카테고리의 다른 글
Springboot 3.x 와 Flyway를 쓰며 테스트/운영 DB 서버 밴더 다르게 사용하는 법 (3) | 2024.12.20 |
---|---|
[error] Apache POI NoClassDefFoundError와 AWS EC2 Alpine Linux (2) | 2024.12.18 |
Flyway 도입 후기: 장점, 문제점, 해결 과정 (2) | 2024.12.07 |