종종 신경쓰지 않아도 되는 것에 꽂혀서 과연 무엇이 더 이득인지를 궁금해하게 될 때가 있습니다. 감사하게도 그런 사람이 저 뿐만은 아니었나 봅니다. 구글링을 통해 여러 사람이 비슷한 질문을 했다는 것을 알 수 있었는데, 여전히 5 % 정도는 해소되지 않은 듯한 찜찜함이 남아있네요. 참고자료1, 참고자료2, 참고자료3
무엇에 관련한 이야기냐구요? 관계형데이터베이스에서 (성능적인 부분에 있어서) row 의 갯수를 늘리는 것이 나은지, 아니면 column 의 갯수를 늘리는 것이 나은지에 대한 것입니다. 사건의 발단은 이렇습니다.
Final Project 로 자신만의 칵테일 레시피를 올리고, 또 다른 사람의 레시피를 손쉽게 찾아볼 수 있는 사이트를 만들기로 했습니다. 칵테일 사진을 직접 올려서 썸네일을 채우는 대신, 색깔만 선택하면 미리 만들어둔 컵 모양의 배경에 실제 칵테일처럼 색깔을 채워넣어 썸네일로 만들어 주는 기능을 넣어보기로 했죠.
기능에 대한 이야기를 마치고 DB Schema 를 구상하려고 보니 썸네일 정보를 어떻게 저장할지 그 방법을 결정해야 했습니다. 사용자가 만든 썸네일을 이미지 정보로 변환해서 받아오는 방법이 있고, 컬러 정보를 받았다가 돌려주면 클라이언트에서 CSS로 재구현하는 방법도 있으니까요. 결국 컬러 정보를 돌려주는 것으로 이야기가 되어 데이터베이스에도 컬러 정보를 저장하게 되었습니다.
"사용자는 여러 개의 색깔 정보를 선택하게 될텐데, 데이터베이스에 이를 저장하려면 어떻게 해야 할까?" 를 고민하다가 다음과 같은 궁금증이 생겼습니다.
- "(thumbnail 테이블에) 여러 개의 컬러 정보를 color1, color2, color3 과 같이 여러 개의 컬럼으로 나누어 하나의 row 에 저장하는 것이 나은가?"
- "여러 개의 컬러 정보를 color 라고 하는 새로운 테이블과 color_thumbnail 이라는 join table 을 만들어 (thumbnail 테이블과) 다대다의 관계로 만드는 것이 나은가?"
1 번 방법은 하나의 row 로 여러 컬러 정보를 한 번에 처리할 수 있지만, 컬러의 종류를 많이 사용하지 않는 경우 불필요한 null 값이 여러 번 반복되게 됩니다.
2 번 방법은 null 값을 제거할 수 있지만, 하나의 썸네일을 위해 다양한 색깔의 정보를 담은 여러 개의 row 를 사용해야 하겠죠. 게시물 하나를 처리하기 위해서 여러 개의 row 의 정보를 받아오는 쿼리문을 작성해야 할테구요.
당장 프로젝트를 진행하는 데에는 크게 고민할 필요는 없는 문제입니다. 저희가 사용할 데이터베이스의 양이 그렇게 많지 않을테니까요. 분명 신경쓰지 않아도 될 문제인데 갑자기 무엇이 더 효율적인 데이터베이스 구성인지가 궁금해졌습니다.
다 건너뛰고 결론을 바로 이야기해보겠습니다.
만약 컬러 라고 하는 정보가 추후에 독립적으로 사용될 여지가 있다면 2 번, 그렇지 않다면 1 번을 선택하자.
스택오버플로우에서 비슷한 여러 질문과 그 답변들을 읽어보다가, 다음의 자료를 통해 (상황은 다르지만) 위와 같은 결론을 도출하게 되었습니다.
MySQL에서 하나의 테이블이 가질 수 있는 컬럼의 갯수는 이론적으로 총 4,096 개 입니다. 실제로는 상황에 따라 그보다 더 적은 갯수만을 사용할 수 있지만, 그렇다 하더라도 10~20 개 정도의 컬럼을 추가하는 건 아무런 문제가 되지 않습니다. 컬럼의 갯수 자체가 문제는 아니라는 것이죠.
대신 고려해야 하는 것은 컬러라고 하는 정보가 어떻게 사용될 수 있는지입니다. 조금 더 쉬운 이해를 위해 컬러 정보를 토대로 레시피를 검색하는 기능을 추가하고 싶다고 가정해보겠습니다.
(row 의 갯수가 늘어나더라도) 다대다 테이블을 구성하는 2 번의 방법을 사용했다면 color
라는 컬럼 하나만 검색 조건에 걸어 검색할 수 있습니다. 어떤 컬러가 되었든 color
라는 컬럼에 그 정보가 저장되어 있기 때문이죠. 이 경우에 처리해야 할 row 의 갯수가 조금 많기는 하지만 검색을 위한 쿼리문은 한결 단순해질 겁니다.
하지만 1 번의 방법에서는 color1
에서부터 color 10
까지의 정보를 전부 비교하고 검색해야 합니다. 어디에 우리가 원하는 컬러 정보가 들어있는지를 알 수 없기 때문이죠. 이 경우에는 row 가 조금 늘어나는 것처럼 보인다 하더라도 컬러와 썸네일을 다대다의 관계로 설정하는 것이 개발 과정에서 더 유리할 겁니다.
저희가 개발하려는 사이트의 기능에서는 컬러 정보가 단독적으로 사용될 필요가 없기 때문에, 1번의 방법을 사용하면 매번 썸네일이 갖는 여러 개의 컬러 정보를 찾아와서 나열해야 하는 불필요한 과정을 반복해야 합니다. 따라서 2 번의 방법보다는, (컬럼이 많은 것 같아보여도) 1 번의 방법을 선택하는 것이 낫다는 결론을 얻게 됩니다.
사실 프로젝트 기준에서 위의 고민은 매우 불필요한 고민입니다. 어떻게 구현하든지 실제 성능에서 유의미한 차이가 나타나지 않을 것이기 때문입니다. 그럼에도 궁금한 점이 생겨서 이것 저것 알아보게 되었고, 그 결과를 이렇게 블로깅으론 남기게 되었네요.
사실 굳이 이렇게 궁금해하실 분들이 있으실지, 또 그런 분들 중에서 과연 몇 분이나 이 글을 보실지도 잘 모르겠습니다. 다만 위의 정보는 스택 오버플로우의 답변을 토대로 제 나름대로 추측한 것이기 때문에 무조건적으로 이게 옳다라고 할 수는 없다는 점을 알려드리면서 오늘은 여기에서 마쳐볼까 합니다.