본문 바로가기
서버/스프링

스프링을 배우기 전에(4) - ORM

by 나이아카 2023. 5. 10.

 중간중간 서버 공부를 이어나가다가 어느 순간 놓고 있었는데, 다시 서버를 시작해보고자 하는데 또 다시 여러가지 키워드들이 발목을 잡는 군요. 시작부터 끝까지 혼자 공부하고 개발한다는 게 쉽지는 않은 것 같습니다.(오히려 회사에서 배울 때가 더 쉬웠을 지도...)

 이 글은 스프링을 배우기 전에 개발자로서 공부하는 내용을 담고 있으므로 지나가던 재야의 고수 분들은 언제든 지적 부탁드립니다. 또한, ORM에 대해 공부하시는 중에 제 글을 발견하셨다면 꼭 검증 과정을 거치시길 바랍니다.


ORM이란?

ORM은 Object-Relational Mapping의 줄임말입니다. 한국말로는 객체-관계 연결이라고 합니다. 말 그대로 객체 지향 언어에서의 객체와 관계형 데이터베이스의 관계를 maaping 하는 역할을 하는 것입니다. 이는 객체 지향 언어에서 객체로 불리는 것들을 객체의 형태 그대로(기존 OOP에서 사용하던 class를 그대로) 관계형 데이터베이스의 관계(RDB의 테이블)와 대응되도록 작업을 해준다는 것을 의미합니다.

 

패러다임의 불일치

 OOP로 줄여부르는 객체 지향 프로그래밍과 RDB라 부르는 관계형 데이터베이스에서의 데이터 관리 방식은 명백하게 다릅니다. 애초에 OOP는 데이터를 위한 코딩 방식이 아니기 때문에 데이터 관리 방식에 가까운 RDB와의 직접적인 비교가 어렵습니다. 각 언어가 지향하는 패러다임 자체가 다르기 때문입니다. 그렇기 때문에 OOP에서 사용하는 데이터라 볼 수 있는 '객체'는 사물을 추상화하는 대상에 가깝고 또한 그런 특성에 따라 캡슐화 및 상속과 같은 객체를 표현하는 방식이 좀 더 다채롭습니다. 이러한 객체를 이용해 인스턴스로 사물을 구체화하는 OOP의 관점은 관계를 기준으로 데이터베이스를 작성하는 RDB와 묘하게 엮을 수 있을 것 같으면서도 전혀 다른 개념에 속해있습니다. 이렇듯 각 프로그래밍 언어의 방식이 각기 다른 방향으로 발전해 언어의 활용 방식이 달라지는 것을 패러다임의 불일치라고 합니다.

 

ORM의 장점

 사실 우리는 여타 서버들과의 통신을 할 때 대부분 ORM을 사용하곤 합니다. 특히 안드로이드 개발자인 저는 서버와의 통신 과정에서 주로 class 형태의 완성된 데이터를 서버에서 받아옵니다. 주로 Retrofit과 같은 라이브러리를 이용해서 json과 같은 형태의 데이터를 심지어 ResponseClass로 완성까지 시켜 반환받죠. 그러다보니 클라이언트 개발자로서 ORM을 딱 봤을 때는 오히려 당연한 이야기라 쉽게 이해할 수 없는 부분들이 많았습니다.

 클라이언트는 서버에게 데이터를 요청하고, 서버는 클라이언트에게 데이터를 주죠. 그것도 원하는 class의 형태에 맞게 json과 같은 주고 받기 편한 형태로 말입니다. 이 과정에서 서버는 의도치않게 ORM의 역할을 하고 있습니다. 서버가 어떤 방식으로 데이터베이스에서 데이터를 가져오고 그것을 가공했는지는 모르지만, 결과적으로 클라이언트에게 필요한 Class를 제공해주게 됩니다. 그렇게 생각해보니 클라이언트 개발자는 ERD의 존재에 대해서 알 필요가 없군요. 그렇습니다. ORM을 이용한다는 것은 객체를 설계하고 나면 그에 맞는 데이터를 가공된 상태로 받아볼 수 있다는 것이라고 볼 수 있습니다.

 물론, 이는 클라이언트 - 서버의 이야기이고 극단적으로 얘기한 부분이라 ORM을 쓰면 아예 객체만 만들면 테이블까지 다 생성해주는 건가? 라는 생각이 들 수 있는데 그건 아닙니다. 데이터베이스매니저와 서버 개발자가 분리되어 있는 회사가 아니라면 대부분은 백엔드 개발자가 서버 API 구축과 ERD 개발을 같이 진행하게 될 텐데, 현재 테이블의 데이터를 이용해 참조 가능한 객체를 생성해서 ORM을 통해 상태를 처리함으로서 내부적으로 SQL 코드를 대신 작성해주는 형태로 도움을 받을 수 있습니다. 물론 SQL에 정통해서 하나하나 작성하는 것이 더 효율적일 수도 있지만, 일반적으로 생성해야 할 객체의 참조가 여러개라면 결국 그 참조를 모두 채우기 위한 복잡한 코드를 작성해야 합니다.

 이렇듯, 블랙박스 형태로 SQL 코드를 작성해주는 ORM 프레임워크의 도움을 받으면 개발자는 실제적으로 OOP에 맞는 개발 방식을 고수할 수 있게 됩니다. 개발자가 작성한 코드 상에서는 SQL의 절차지향적 코드를 줄여줄 수 있기 때문이죠. 이는 코드가 동일한 형태를 이루게 된다는 것을 의미하며, 곧 코드의 가독성 향상으로 이어질 수 있습니다.

 또한 개발자는 객체에 대한 정보만 알고 내부적인 코드는 따로 구현되기 때문에 DBMS에 대한 종속성이 줄어들게 되는데, 이는 요즘 굉장히 다양한 DBMS를 사용중힌 트렌드에 있어 또 하나의 메리트가 될 수 있을 것 같습니다.

 

ORM의 단점

 그러나 자동으로 완성시켜주는 대부분의 프레임워크가 늘 그렇듯, 내부 구조가 세계에서 가장 최적화 된 부분이다 라고 하기에는 코드는 매 순간 데이터의 저장 방식이나 사용 방식에 따라 무수히 많은 경우의 수가 생겨나며, 이 중 어느것이 가장 효율적인지는 항상 검증 과정을 거쳐야 합니다. 하지만 ORM의 경우 매번 효율적으로 작성해 줄 수 없으며 이는 속도의 저하가 신뢰성의 하락으로 이어질 수 있습니다.

 더욱이 옛날 방식(프로시저 구조)으로 작성된 시스템의 경우, ORM을 도입하기 위해 오히려 잘 만들어진 코드를 제거해야 하는 부수적인 리소스 소모가 일어나기 때문에 어떤 부분이 더 효율적인지 따져가며 확인해야 합니다.

 또한 ORM이 대신 SQL 코드를 작성해주기는 하지만, 개발자가 원하는 방식의 객체를 100% 만들어줄 수 있는 것은 아닙니다. 또한, 그러한 객체를 만들기 위해서는 더 신중하게 테이블을 설계해야 할 필요가 있습니다. 더욱이 DB 매니저가 따로 있는 경우, 협업을 통해 더욱 뛰어난 형태의 코딩을 실시할 수 있기 때문에 제대로 된 DBA가 있다면 굳이 사용하지 않아도 ORM의 장점과 같은 것들을 가져갈 수 있습니다.

 

ORM의 종류

자바: JPA, Hybernate

파이썬: SQLAlchemy, Django의 내장 ORM

Node.js: Sequalize

 


 새로운 프레임워크를 사용할 때는 늘 그렇듯, 기존 바닐라 형태의 코드 작성법보다 분명 편리한 것들을 많이 제공하지만, 그 내부의 것들을 아무것도 모르고 사용하기 시작하는 순간 효율성이 떨어지고 구현 난이도가 올라갈 수 있습니다. 이는 명확하게 내부 구조를 이해하고 사용해야 프레임워크를 제대로 이용하고 있다고 생각하면 될 것 같습니다.

 스프링을 공부하는데 코드를 떼기도 전에 배워야 할 것들이 너무 많다는 것을 깨닫는 중입니다... 안드로이드를 처음 배울때는 오히려 아무것도 몰라서 막 하다보니 금방금방 진도가 나갔던 것 같은데, 요즘은 본업도 있고 한 발 떼는 것도 나중을 생각하면 조심스러워지니 실제로 코드를 작성하기가 겁이 나네요. 어서 빨리 공부에 박차를 가하고 본격적으로 시작해봐야겠습니다.

댓글