다른 부서 팀원분이
'DB설계하실 때 컬럼이 30개 정도되면 보통 쪼개는지 궁금'
하다고 질문 주셨다.
나도 궁금 🧐❓
인터넷에 서치한 결과,
1) 무조건 나눠라,
2) 컬럼 30개 정도는 괜찮다,
3) 데이터 타입에 따라 고민해봐라,
등등 여러 의견들이 있었다.
mysql 8.0 기준으로 4096개의 컬럼까지 MAX로 사용할 수 있다고 한다.
"There is a hard limit of 4096 columns per table, but the effective maximum may be less for a given table. The exact limit depends on"
테이블당 적정 컬럼수와 관련된 권고사항은 없다. 데이터 모델링에 따라 테이블 컬럼수도 다르고 컬럼 수 MAX로 넣어주어도 상관은 없다고 한다.
하지만, 테이블을 쪼개는 이유는 이후에 테이블 타입이 변경될때 등 한테이블에서 rebuilding 하는 것이 어렵기 때문이라고 한다. 매번 필드를 추가했을때 모든 필드에 값이 들어가지 않는 경우가 생긴다면 공간 낭비가 생길수도 있을 것이다.
정리하자면, 처음부터 쪼개서 설계하는 것이 확장에 용이하다고 한다.
기본적으로 테이블의 Row 수가 많을수록 Index에 대한 부하가 따르고, 테이블의 컬럼 수가 많을수록 I/O에 대한 부하가 걸린다. 그렇다고 모든 테이블이 분리를 통해 성능 개선의 효과를 보는 것은 아니다. 하지만 대용량이면서 성능 이슈가 있는 테이블은 분리를 통한 성능 개선을 검토해 볼 필요가 있다.
테이블의 컬럼 개수와 데이터 양을 종합적으로 판단하여 양에 따른 대용량 테이블인지 컬럼 개수에 따른 대용량 테이블인지 정리한다.
만약 컬럼 개수에 따른 것이라면, 트랜잭션의 특성에 따라 테이블을 1:1 형태로 분리하는 수직분할을 하면 된다.
반면 데이터 양에 따른 것이라면, 적절한 파티션을 선택하고 여러 개의 물리적 스페이스로 저장하는 수평분할을 하면 된다.
어떤 사람은 데이터 테이블 사용 목적에 따라 정규화를 고민해보라고 했다.
컬럼수/데이터용량 <-> 속도
는 절대적으로 반비례한다며,,무조건 정규화 하세요... 쓰지 않을 데이터는 남기지 마세요... 로그성 데이터는 로그 디비에 남기세요... 휘발성 데이터는 항상 지워주세요. 실시간 랭킹 같은 것은 자제해주세요..
컬럼을 늘릴때, 테이블에 인덱스를 걸어준다고 하더라도 인덱스조건에 해당하는 row 전체를 읽기 때문에 한번에 읽을 데이터의 값이 커지고 IO에 부담을 준다고 한다.
DB 컬럼은 linked list 로 구성되어있어, 인덱스를 사용하더라도 해당열 전체 값을 가져오기 때문에 컬럼이 늘어날수록 데이터 조회 비용은 늘어난다. 컬럼들이 모두 INT 등과 같이 작은 데이터타입을 다룬다면 문제는 없겠지만, VARCHAR/TEXT 등과 같이 큰 데이터타입을 다룬다면 문제가 될 것이다. '사용하지 않더라도 읽어야 하는' 일이 생길 수 있는 것.
- 게시물을 가져올때 분리된 테이블을 JOIN 해서 가져오면 성능이 나빠지지 않아요?
-> ( NO, 인덱스를 사용해서 정확하게 조회하면 훨씬 빠른 속도 )
-> ( 큰 데이터를 담은 컬럼을 별도의 테이블로 분리해서 JOIN 해서 조회하기 )
컬럼수 100개로 MyISAM과 Innodb 에서 관련된 성능 테스트를 진행한 사람이 있었다. 해당블로그 결과는 이렇다. CHAR/INT 컬럼의 경우(고정크기타입) 컬럼 수를 100개까지 늘려도 성능에 무리가 없었지만 VARCHAR 컬럼의 경우(동적크기타입) IO가 slowdown 되어 성능에 큰 영향을 준다.
참고링크