🪄 요일별 운영시간 저장 형태
가게의(장소의) 월화수목금토일 운영시간을 어떻게 저장하면 가장 효율적일지 고민해보았다.
결론:
운영시간 테이블을 따로 두고
mon_open, mon_close, ..., sun_open, sun_close라는 총 14개의 속성에 시간을 저장해두는 방식
이유:
- [open과 close 분리] 요일별 open과 요일별 close는 의미가 다르므로 open, close로 분리한다.
- [요일별 분리] 모든 장소, 행사의 운영시간은 요일별로 존재한다. 결국 월화수목금토일을 검토하는 것이 공통적일 것임.
- [휴무일과 운영일] 휴무일을 별도를 저장해두는 게 아니라, open 에 별도의 값을 통해 식별하면 효율적일 것임.
🪄 관련 생각들
처음부터 요일별 open, close를 저장해야곘다고 떠올린 것은 아니다.
다양한 생각들이 오갔다.
1. 운영시간 데이터를 받아와서 Stirng 타입 속성으로 박아두기
- 받아온 운영시간 String을 한번에 저장해두고 String으로 표기해주는 방식도 생각해봤는데, 단점이 많다. 수정도 어렵고 출력형식을 바꾸고 싶은 경우에도 깔끔하지 않다. 큰 고민 없이 기각한 전략이다.
2. 요일별 운영시간 14개 컬럼을 operation 테이블로 따로 빼지 않고, culture 테이블에 몰아서 넣기
- 14개의 운영정보 속성을 culture 테이블에 몰아 넣겠다고 생각한 이유는 날짜별 culture를 조회할 때 운영시간도 함께 가져와서 띄워주게 되기 때문이다. 그래서 한 테이블만 조회해서 모든 정보를 가져오는 것이 낫다고도 생각을 했었다.
- 그러나 속성이 많아져 하나의 테이블이 방대해진다. 운영시간 관리 측면에서도 깔끔한 느낌이 없어진다.
- 컬럼 수에 대한 고찰을 해보았다. 시간 데이터 14개정도는 성능을 신경쓰지 않아도 된다고 판단했다.
- 그러나 일반적으로 내가 가지고 있는 생각은, 의미 단위로 쪼개는 것이 관리측면에서 좋다는 것이다. operation 데이터는 변동이 잦기도 하니까 테이블을 쪼개는 것이 좋다고 생각했다.
▼▼ 데이터베이스에서 관련 개념은 수직 분할이다.
이참에 정리해둔다.
🪄 테이블 분할하기: 수평 / 수직 분할
테이블을 분할하는 것은 "수평 분할"과 "수직 분할" 개념이 있다.
이는 반정규화 기법이다. 일반적으로 수직분할을 선택하는 이유는 이러하다.
1. 분할하는 컬럼의 용도가 나뉘기 때문 (조회 위주 / 갱신 위주)
2. 특별히 자주 조회되는 컬럼이 있음
3. 특정 컬럼 크기가 아주 큼
4. 특정 컬럼에 보안을 적용해야 함
이 서비스의 경우 운영시간 기준 필터링이 필요할 수도 있어서 수직분할을 적용했다.
아무튼 공부 목적으로 수평분할과 수직분할을 정리해둔다.
수평 분할 | 수직 분할 | |
개념 | row를 기준으로 나눔 | 컬럼을 기준으로 나눔 |
이유 | row 수가 많을 수록 인덱스 관련 부하가 커진다. [인덱스 관련 성능] - 데이터량이 몇천만건을 넘어가면 인덱스를 도입하더라도 SQL 성능이 나쁘다. - 인덱스 생성시 부하가 커진다. - 인덱스를 찾아갈 때도 depth가 깊어져, 인덱스의 크기가 커질수록 더 많은 성능 저하 개선: 파티셔닝 테이블에 많은 양의 데이터가 예상될 경우, 테이블을 물리적으로 분리하여 여러 테이블스페이스에 쪼개 저장하는 구조로 개선하자. - Range 파티션: 범위, 날짜, 숫자값으로 분할 - List 파티션: 특정 값에 따라 분리저장 - Hash 파티션: 해싱 알고리즘으로 분리 - Composit 파티션: Range + Hash |
컬럼 수가 많을수록 I/O 관련 부하가 커진다. [로우 체이닝 증가] 로우의 길이가 너무 커서 하나의 블록에 저장되지 못하고 다수의 블록에 나누어져 하나의 로우가 저장되는 형태 [로우 마이그레이션 증가] 데이터 블록에서 수정된 데이터를 해당 데이터 블록에 저장하지 못하고 다른 블록의 빈 공간을 찾아 저장하는 방식 개선: 테이블 분할 수많은 컬럼을 동시에 저장하는 경우는 드물다. 조화가 빈번한 데이터를 묶어 테이블을 분할하자. |
Ref:
분리를 통해 무조건 성능개선을 보이는 것은 아니다. 최적화는 필요한 경우를 확인한 이후에 신중히 하도록 하자.
'Database' 카테고리의 다른 글
[상속관계 매핑] 싱글 테이블 전략을 선택한 이유 (0) | 2024.05.16 |
---|---|
[MySQL + JPA] field 'mark_id' doesn't have a default value | 그리고 auto increment (0) | 2024.05.11 |
Docker Mysql Container의 sql 파일 꾸준히 백업: crontab 사용 (0) | 2024.01.04 |
[DB] 인덱스 사용 이유 이해하기 (0) | 2023.10.17 |
[H2] Column이 drop 되지 않음 | JPA Bean을 직접 주입하는 실습 중 (0) | 2023.01.25 |