ORM vs SQL

Heehong Moon
bgpworks
Published in
4 min readSep 15, 2017

Java의 spring, python의 django, ruby의 rails 등 웹프레임웍에 기본적으로 포함되는것 중 하나가 ORM이다. Object Relation Mapping이라는 말 그 자체의 의미대로 Relation을 Object에 맵핑 하는것을 의미한다. 나는 개인적으로 ORM을 사용해서 꽤 큰 서비스를 해본적은 없지만, ORM보다는 SQL을 그대로 사용하게 훨씬 좋다고 생각한다.

ORM의 장점

ORM을 사용하면 DB의 schema를 그대로 OO의 class로 맵핑하고, 별도의 SQL문을 사용하지 않고 schema 를 디자인할 수 있으며 query를 단 한줄도 안써도 DB의 데이터를 추가/수정/삭제가 가능하다. 게다가 특정 DB에 한정 되지 않기 때문에 나중에 어떤 DB로든 쉽게 migration 가능하다.

ORM의 단점

ORM을 사용하면 기본적으로 자동으로 생성되는 query를 사용하게 되고, 추후에 속도와 같은 문제가 생기면, 그 부분만 내가 직접 sql을 사용 가능하다. 하지만 이렇게 되면 시스템이 복잡해질 수록 직접 추가한 sql의 비율이 점점 많아질것이고, 코드가 점점 복잡해질 수 있다.

특정 쿼리마다 몇개의 field(column)만 가져오고 싶어도 쉽게 구현하기 힘들고, 기본값은 모든 값을 가져오게 되어 performance에 영향을 준다.

SQL

sql은 꽤 오래된 하나의 DSL이며, sql자체가 이미 DB에서 데이터를 관리하기 위한 abstraction이 된 것이라고 볼 수 있다. DB마다 sql이 조금씩 다르며 내가 사용하는 DB에 맞게 query를 작성 할 수 있다.

실제로 데이터 양이 적을때는 내가 원하는 결과를 얻기 위한 query를 아무때나 짜도 상관없지만, 데이터가 많이 쌓이기 시작하면 같은 결과라도 내가 어떻게 query를 하는가에 따라 performance 차이가 엄청나게 크다. 그래서 큰 시스템에서 query를 추가할때는 query planner를 돌려보면서 index를 잘 사용하고 있는지 등을 체크해야 한다.

내가 필요한 것 = SQL + Mapping

내가 필요한것은 ORM이 아니라 sql을 그대로 사용 할 수 있으며, 데이터 또는 class에 맵핑된 결과를 주는것이다. 이런 철학으로 사용되는 라이브러리는 clojure에는 yesql(https://github.com/krisajenkins/yesql), JAVA쪽에는 mybatis(http://www.mybatis.org/mybatis-3/)가 있다.

yesql은 clojure에서 sql으로 query를 할 수 있게 도와주는 라이브러리이다. plain sql파일에 comment를 통해 query의 이름을 지정하고, 정의된 이 query를 clojure코드에서 마치 일반 함수 처럼 call하면 db에 query가 되는 형식이다.

-- name: users-by-country
SELECT *
FROM users
WHERE country_code = :country_code

위 sql을 실행은 :country_code를 파라메터로 넣어서 users-by-country라는 함수를 실행하면 된다.

;;; sql파일을 parsing해서 clojure function으로 만듬
(defqueries "some/where/users_by_country.sql"
{:connection db-spec})


;;; 만들어진 sql 함수 사용
(users-by-country {:country_code "GB"})
;=> ({:name "Kris" :country_code "GB" ...} ...)

yesql의 장점은 마치 sql이 일반 함수와 크게 다르지 않게 보이며, query의 결과를 clojure data structure로 리턴한다. 또한 plain sql을 그대로 사용하기 때문에 특정 DB에만 있는 syntax도 사용 가능하다.

yesql의 단점으로는 sub-query의 재사용이 불가능하다는 점, where 절에 들어가는 parameter개수가 실행 시점마다 다른 경우 사용이 불가능하다는 점이 있다. yesql자체를 만들기도 쉽기 때문에 이런 단점을 보완한 새로운 라이브러리를 만들거나 yesql에 contribute해도 될듯하다.

--

--