티스토리 뷰

성균관대학교 학생회 공약 모아보는 웹페이지 제작 프로젝트 - (2) 수집한 정보 데이터베이스 모델링하기


171129
  
Python으로 신문기사를 크롤링한 다음, 4명 팀원이 2014년부터 2017년 중 1년씩 맡아서 총학과 단과대의 공약 이행 데이터를 수집하기로 했다. 보통 성대신문이 제공하는 평가는 9월 무렵 중간평가 형태로 제공되거나, 11월경 최종평가 특집기사 형태로 이루어졌다.
  
신문기사다 보니 공약의 내용이나 이행여부도 전부 줄글로 쓰여 있다. 그래서 각자 1년치 데이터를 조사하기 위한 기준이 필요했다. 총학과 단과대의 기준을 조금 다르게 설정했다.
  
총학 데이터베이스 구분기준 - Attribute들이라고 해야 하나.

year : 조사 연도 (integer)

name : 총학생회 이름(string)
campus : 캠퍼스(string) - 공통, 인사캠, 자과캠
category : 공약 분류(string) - 교육, 복지, 등록금, 문화, 소통과 같은 공통공약과 해당 총학생회에서 진행한 특수공약으로 나누었다. 이를테면 2014년에는 ‘예산’분류가 추가되어 있고, 2016년의 경우 ‘수강신청’이 따로 분류되어 있었다.
content1 : 공약 내용(string)
enforce : O, X, △, -(string) 4개로 나누었다.
공약을 이행했다고 평가받으면 O, 이행하지 못했으면 X, 다른 방식으로 대체이행한 경우 / 절반만 이행한 경우 △, -는 기사 작성 시점에서 이행여부를 확인할 수 없는 경우이다. 보통 마지막 -는 내년 시행 예정, 다음 학기 시행 예정으로 기사에 언급된 경우이거나 공약에 대한 평가가 없는 경우 등이 해당한다. 즉 -는 ‘현 시점에서는 확인할 수 없음’이다.
detail : 내용 보충이 필요한 경우 기재하는 비고란이다. 공약을 이행하지 못한 이유가 기사에 있는 경우, 대체공약으로 변경될 수밖에 없던 이유 등을 기록했다. 



  
단과대

year, name, campus, enforce, detail - 위와 동일

self-gov : 단과대학 이름(string). 사회과학대학, 공과대학 등등 학부대학을 구분하는 이름.
content2 : content1과 동일


기준을 설정하고 수집한 데이터의 결과는 다음과 같다.

성대신문의 공약 평가가 객관적인지, 사실을 충실히 반영했는지 확신할 수는 없다. 이 프로젝트를 진행하는 네 명은 철저히 외부자이기 때문.
일단 성대신문의 평가가 공정하고 객관적이라는 전제 하에 수집하고, 성대신문의 평가 논조를 위에서 정한 Enforce 기준으로 분리했다.


총학 데이터베이스


단과대 데이터베이스





그런데, 이렇게 엑셀 형태로 데이터를 하나의 Table로 만든 다음 c9에 데이터베이스로 저장하고 활용하려니 문제가 있었다.

1. 웹페이지에서 데이터를 뿌려줄 때는 연도별 - 총학/단과대 여부 - 캠퍼스 - 카테고리 순서대로 데이터를 Drilldown해야 하는데, 팀원 중 누구도 Ruby on Rails에서 데이터베이스 값을 불러오는 SQL문을 쓸 줄 모른다.

2. 대안으로 Ruby 언어의 if 조건문으로 하나씩 데이터를 가져와야 했는데, 데이터를 가져오는 속도가 느려지고 코드가 너무 복잡해진다는 문제가 발생했다. 특히 Ruby로 html을 구성해야 하다 보니 if 조건문이 복잡해져서 html문으로 변환하기엔 너무 어렵다.

그래서 짜낸 해결방안으로는 '모델 간 상하관계' 형태를 Drilldown형태로 계속 만드는 것이었다. 가장 상위모델에 연도, 그 하위모델에 총학/단과대 모델, 그 아래에 캠퍼스 모델, 다음으로 카테고리 모델이 이어지는 식이다. 효율적인 방법도 아니고 엑셀로 만든 데이터베이스를 다시금 나눠야 하는 문제가 있었지만, 결국 나누는 과정까지 도달했다.



가장 상위모델 year



다음 모델 location


year 모델에 있는 각 데이터들 - 2014년부터 2017년까지 -은 2014년부터 2017년까지 각각 year_id가1,2,3,4로 자동 지정된다. year 모델에 belongs_to의 관계를 갖는 하위모델인 location은 각각의 연도에 해당하는 campus를 구분했다. 
즉 location 모델의 데이터 year_id=1(2014년)의 첫 번째 row는 '공통'이고, 이 row는 location_id=1이라는 값을 자동으로 부여받는다. year_id=2(2015년)의 두 번째 row는 '인사캠'을 의미하고, 이 row는 location_id=5가 된다. 5번째 row에 해당하는 값이기 때문.

이 location_id는 다음 하위모델의 데이터를 연결하는 기준이 된다.


하위모델 category


이런 식으로 이어진다. category라는 모델은 location의 하위모델이고, location_id=1은 '2014년의 총학 + 공통 공약'이다. 그 공약의 세부항목으로 각각 '등록금', '문화', '복지', '소통'이 있다. 
category_id가 1이면 2014년 총학의 공통 공약 중 '등록금'항목이고, 2는 '문화'항목, 3은 '복지'항목을 의미하는 식이다.

이렇게까지 분류가 나뉘면, 그 다음 데이터는 개별 항목들의 모든 공약명, 이행여부, detail이 있을 것이다.



가장 하위모델 content


이렇게 데이터베이스가 만들어질 경우, 연도별 + 캠퍼스별 + 공약 분류별로 구분해서 Ruby if 조건문을 설정할 수 있다. 각 공약별로 조건문을 한 번씩 써야 하는 불편함이 있지만, 현재까지 배운 수준에서 구현할 수 있는 최선의 방법이었다. 
(그나마도 csv파일로 데이터베이스 만드는 방법은 전적으로 구글 검색과 stackoverflow의 힘이었다.)


포스팅을 하는 지금, 한 기업에서 인턴 일을 하며 데이터베이스 구축의 기본을 어깨너머로 익히고 나니, 아무것도 몰라서 데이터를 전부 다시 뒤엎는 노동이 얼마나 힘든 것인지 새삼 깨달았다. 물론 지금 알고 있는 지식 수준으로는 저것보다 더 나은 구조를 짤 자신이 없기도 하지만. 데이터베이스의 기본을 알아야 이런 노동 없이 데이터베이스를 제대로 설계할 수 있다는 걸 깨달았다.




댓글
댓글쓰기 폼