아.. 컬럼 하나에 다중 값을 넣는 문제에 대해 묻고 계신 듯 합니다. 요는 어떤 레코드는 N, 어떤 레코드는 N/M 이런식으로 값을 가질 수 있는 경우인거죠?
이런 경우는 별도 컬럼.. 또는 컬럼의 성격에 따라서는 테이블을 분리해야 정규화가 됩니다.
본문의 예에서 컬럼 하나에 N,Y,M 과 같이 넣는 것은 역정규화입니다.
장/단점을 논하기에 앞서 DB를 설계할 일이 있고 이 일을 제대로 하고 싶으시다면, 처음에는 무조건 정규화해서 설계하는 연습이 필요합니다. 역정규화는 설계에 대한 이해가 충분해지고 어느 정도 경험을 쌓였을 때 분명한 목적을 가지고 수행해야지 그렇지 않으면 단지 운에 맡기는 것과 다르지 않기 때문입니다.
사실 역정규화는 "살을 주고 뼈를 취하는것"에 비유할 수 있습니다. 정규화는 보편적으로 빠르지만 역정규화는 치명적으로 느려지는 부분을 허용하면서 내가 필요한 부분을 더 빠르게 만들겠다는 목적이 있는 겁니다.
"테이블로 분리한 정규화"와 "컬럼 하나를 사용한 역정규화"를 비교해서 왜 그런지 설명해보면..
정규화했다면 N,Y,M을 얻기 위해 별도 테이블을 JOIN 한 후 GROUP_CONCAT() 해야 얻을 수 있는 값을 이미 컬럼 하나에 저장하고 있기 때문에 SELECT 절에서 참조할 때는 역정규화한 모델의 성능이 좋습니다.
하지만 "Y" 를 포함한 레코드를 찾아야 한다면 역정규화 쪽은 인덱스를 제대로 활용할 수 없기 때문에 테이블 전체를 스캔하는 극악의 상황이 발생하겠죠.
여기서 과연 "내줄 만한 살"이고 "취할 만한 뼈"인지는 비즈니스적으로 판단합니다.
N,Y,M을 SELECT 할 때만 사용하고 WHERE 절을 통해 필터링할 일이 전혀 없다면.. 이건 일단 "내줄만한 살"이죠. 이런 경우에는 역정규화를 해도 되기는 합니다만.. 앞으로의 시스템 변화를 완벽하게 예측하기는 어렵기 때문에 꼭 취해야하는 뼈가 아니라면 섣부르게 역정규화하지 않는 것이 좋습니다.
정규화로 넘어와서 생각해보면.. 여기서 다시 선택지가 두 가지가 됩니다.
각각의 컬럼이냐? 별도 테이블이냐?
이건 N,Y,M 외에 앞으로 새로운 값이 등장할 수 있는가의 문제입니다. 시스템이 유지되다가 어느 순간 O,P,Q,R 과 같이 계속 값이 추가되어야한다면 컬럼은 곤란하겠죠. 이런 경우라면 애초에 테이블을 분리했어야 맞는게 됩니다.
이야기가 길어졌는데 상황에 맞게 적절히 취사 선택하시기 바랍니다.