다소 도발적으로 들리는 제목이고, 실제로 도발적이지만, 사실 이 글은 작성한지 2년이나 지난 포스트를 '이제서야'보고 작성하는 글입니다. 먼저 그 문제의 글부터 보시죠.


ORM is an anti-Pattern

원문 : http://seldo.com/weblog/2011/08/11/orm_is_an_antipattern


그리 긴 포스트가 아님에도 불구하고, 친절하게 11줄 요약(... 이게 요약인지)까지 해 주었습니다. (참고 : TL; DR은 Too Long, Didn't Read의 약자입니다. 한 마디로 '너무 길어 읽지 않음' 이랄까요..

  • ORM is initially simpler to understand and faster to write than SQL-based model code
       ORM은 SQL기반 모델 코드에 비해 최초에는 쉽게 이해할 수 있고 빠르게 작성할 수 있다.
  • Its efficiency in the early stages of any project is adequate
       대부분의 프로젝트의 초기에는 ORM을 사용하는 것이 꽤 효율적이다.
  • Unfortunately, these advantages disappear as the project increases in complexity: the abstraction breaks down, forcing the dev to use and understand SQL
       불행히도, 프로젝트의 복잡성이 커질 수록 이러한 장점은 사라진다: 추상화는 무너지고, 개발자들은 SQL을 직접 사용해야하고 이해해야 한다.
  • Entirely anecdotally, I claim that the abstraction of ORM breaks down not for 20% of projects, but close to 100% of them.
       정말 개인적인 경험에 따르면, ORM의 추상화는 프로젝트의 20%에서만 사용될 수 없는 것이 아니라 거의 100%에서 사용할 수 없게 된다.
  • Objects are not an adequate way of expressing the results of relational queries.
       객체는 관계형 쿼리들의 결과를 표현하는 데 좋은 방식이 아니다.
  • The inadequacy of the mapping of queries to objects leads to a fundamental inefficiency in ORM-backed applications that is pervasive, distributed, and therefore not easily fixed without abandoning ORM entirely.
       쿼리 결과를 객체로 매핑하는 것이 적절치 않기 때문에, 여기저기서 마구 존재하는, ORM을 사용하는 어플리케이션들은 근원적으로 비효율적이다. 또 그러므로, ORM을 완전히 포기하지 않는 이상 고치기도 쉽지 않다. 
  • Instead of using relational stores and ORM for everything, think more carefully about your design
       모든 상황에 대해 관계형 저장소와 ORM을 사용하는 대신 설계에 대해 좀 더 주의 깊게 생각해보라.
  • If your data is object in nature, then use object stores ("NoSQL"). They'll be much faster than a relational database.
       사용하는 데이터가 본질적으로 객체형이라면, 객체 저장소("NoSQL")를 이용하라. 객체 저장소들이 관계형 데이터베이스보다 훨씬 빠르다.
  • If your data is relational in nature, the overhead of a relational database is worth it.
       사용하는 데이터가 본질적으로 관계형이라면, 관계형 데이터베이스에 오버헤드가 있다고 해도 쓸만한 가치가 있다.
  • Encapsulate your relational queries into a Model layer, but design your API to serve the specific data needs of your application; resist the temptation to generalize too far.
       관계형 쿼리들을 모델 레이어 내에 캡슐화하라. 하지만 특정 데이터에 대한 어플리케이션의 요구에 맞게 API를 설계하라. 과도하게 일반화하려는 유혹을 견뎌내라.
  • OO design cannot represent relational data in an efficient way; this is a fundamental limitation of OO design that ORM cannot fix.
       객체지향 설계는 관계형 자료를 효율적으로 표현할 수 없다. 이것은 ORM도 해결할 수 없는 객제지향 설계의 근원적인 한계이다.

  • 이마저도 길다고 하시는 분들을 위해 이 11줄 요약을 다시 한 번 요약해보면 다음과 같습니다.

    1. ORM은 개발 초기에만 쓸만하다. 

    2. 어플리케이션이 조금만 복잡해져도 HELL이 된다. 해 본 사람은 알 거다.

    3. 관계형 데이터베이스와 ORM을 쓰지 말라는 게 아니라, 관계형 데이터의 모든 것을 객체지향 설계에 주입하려고 하지 말라는 거다.


    어떤 분은 이 글을 읽고 ORM의 사용에 대해 찬성하기도, 혹은 반대하기도 할 것입니다. 하지만 ORM에 대한 절대적인 반대, 반감을 이끌어 내려는 것이 원 저자의 의도는 아니라고 생각합니다. 원 저자가 얘기하려고 하는 것, 그리고 제가 받아들인 바는, '객체 지향 설계라는 것이 지고지순한 선인 것은 아니다. 필요에 따라 우회할 줄 알아야 한다.' 라는 것이라고나 할까요.

    개인적으로 이런 글을 좋아합니다. 어떤 문제에 대한 '해결책'이라 불리는 것이 나왔을 때, 기계적으로 그것을 대입하는 것이 아니라, 똥인지 된장인지 알고 쓰자는 그런 류의 글 말이지요. 

    과거 JavaWorld에 이런 류의 글이 나와 논란이 된 적이 있었습니다. 바로 그 유명한 "Why extends is evil" 입니다. 수 많은 독자들이 이 글에 문제를 제기했고 급기야 '당신이 뭔데 OOP의 기본을 부정하냐?'라는 비난섞인 댓글까지 난무했었습니다.(한때, JavaWorld는 엄청 활동적인 사이트였었죠...) 하지만 이 글의 저자는, 이 도발적인 제목 아래, '클래스 상속, 제대로 설계하지 않고 쓰면 독이 된다. 그리고 상속보다는 인터페이스를 이용해라.'라는, 지금에와서는 지극히 상식적인 내용을 다뤘던 것이었습니다.  나중에 이 저자는 다시 글을 작성하여 본래의 의도를 다시 설명하기에 이릅니다. .... 나중에 기회가 되면 이 글에 대해서도 언급해보기로 하죠.


    그래서 저의 입장은 뭐냐구요? "애매"합니다. 하지만 확실한 것은, ORM을 사용한다 하더라도 결과적으로 Native SQL 혹은 ORM specific Query Language를 사용할 수 밖에 없다는 것입니다. 비즈니스의 복잡성으로 인해, 성능 이슈로 인해, DBMS에 특화된 기능을 사용하기 위해 등등. 결국 ORM이 어떤 문제를 해결해 주지만 또다른 많은 문제들을 야기함을 경험적으로 알고 있습니다. (이에 대해 CQRS - Command Query Responsibility Segregation을 주장하는 사람도 있습니다.) 저의 입장은 결국, '상황을 명확히 이해한 뒤에 결정해야 할 듯요?'가 되겠네요... 무책임하게도 말이죠.


    이 부분은 마치, 정규 표현식에 대한 이 미친듯한 센스를 가진 명언(?)을 생각나게 할지도 모르겠습니다. 이 명언을 처음 접하고 미친듯이 웃었었는데 말이죠..

    Some People, when confronted with a problem, think "I know, I'll use regular expressions". 
    Now they have two problems.


    여담입니다만, 외산 솔루션들을 보면(제가 하는 일의 성격상 외산 솔루션들을 분석하는 작업을 많이 하게 됩니다...), ORM을 적극적으로 사용하면서 그로 인한 성능 문제를 해결하기 위해 External Cache를 적극적으로 사용하는 것을 많이 봅니다. 이것이 해결책이 될 수 있을까요? 역시 어떤 부분에서는 해결책이, 또 다른 부분에서는 또다른 문제점을 야기할 수 있을 것입니다. 어쨌든 나중에 기회가 되면 External Cache에 대해서도 다뤄보기로 하죠.


    아참! 혹시나 오해하실까봐 말씀드립니다만, iBatis/MyBatis는 엄밀히 말해 ORM이 아닙니다. 이에 대한 수많은 글들을 찾아보실 수 있을 겁니다.


    무엇이든 객관적인 시각에서, 장점과 단점을 명확히 파악하고, 장점은 취하고 단점은 최소화하는 노력을 기울여야 함을, 우리 모두 알고 있지만 결코 쉬운 일이 아닌 듯 합니다. 인간은, 특히 저는 그다지 객관적이지 않거든요.

    신고
    Posted by Layered 트랙백 0 : 댓글 0

    댓글을 달아 주세요