본문 바로가기

javascript/nodejs

[SQL] Object Relation Mapping

 현대 사회에서는 짧은 시간에도 많은 데이터들이 오간다. 이러한 데이터들은 서버 기능을 하는 호스트에 의해 관리되는 경우가 많으며, 해당 서버에서는 데이터베이스 관리 시스템을 이용하여 데이터들을 체계적으로 관리하고 있다. 

 데이터베이스 관리 시스템으로 자주 사용되는 구조 중 하나인 RDBMS에서는 데이터를 개체간의 관계를 이용하여 관리하는데, 이러한 시스템은 통상적으로 SQL 언어를 사용하기 때문에, 만약 우리가 RDBMS 에 저장된 데이터를 호출하고 싶다면 SELECT와 같은 쿼리를 작성하여 여러 테이블에 저장된 데이터들을 불러올 수 있겠다.

 실제 서버를 운영하는 경우에도 이러한 기조는 변하지 않는다. 클라이언트가 특정 url을 통해 데이터베이스 내에 존재하는 데이터를 요청하도록 구현하고 싶다면, 서버에서는 특정 url 및 메서드 조합에 대응하는 메서드를 만들고, 특정 데이터를 응답할 수 있도록 내부 데이터베이스에 대한 쿼리를 작성한다.

 쿼리를 통해 데이터베이스로부터 추출된 데이터들은 스칼라 값을 가지는데, 보통 서버에서는 해당 데이터들을 내부적으로 관리하는 모델에 대응시켜 사용하는 경우가 많다. 예를 들어 데이터베이스로부터 특정 조건을 만족하는 사람의 목록 덩어리를 얻었다면, 해당 데이터들을 "사람" 에 대한 모델의 배열 형태로 파싱하여 사용할 수 있을 것이다.

 서버 내에서 데이터가 특정 모델의 형태로 관리된다면, 전체 데이터베이스를 이러한 모델 구조를 이용하여 관리하는 것은 어떨까? 자질구레한 쿼리 작업은 특정 시스템에게 맞기고, 사용자는 객체 자체에 집중할 수 있다면 전체적으로 효율성이 높아지는 효과가 있을텐데 말이다. 이렇듯 객체와 데이터베이스를 대응시켜주는 시스템으로 ORM이 존재한다.


ORM

 ORM은 Object Relation Mapping의 준말로,  데이터베이스 내의 데이터와 객체지향 프로그래밍 언어에서의 객체를 매핑하는 시스템을 의미한다. 특정 데이터를 요청하기 위해 필요한 각종 쿼리를 해당 시스템 내부적으로 처리하므로, 사용자는 SQL이 아닌 자신에게 익숙한 프로그래밍 언어를 이용하여 데이터에 접근할 수 있다.

 통상적으로 ORM은 다음과 같은 장점을 가진다.

  1. 쿼리 작업을 시스템 내에서 처리하므로, 로직에 더 집중할 수 있어, 생산성이 높다.
  2. 익숙한 프로그래밍 언어를 이용하여 데이터에 접근할 수 있다.
  3. 통상적으로 ORM이 다양한 DBMS을 지원하므로, 재사용성이 높다.
  4. 직접적인 쿼리 작업이 없으므로 특정 DBMS에 대한 의존도가 낮다.

단점 역시 존재한다.

  1. ORM 시스템의 설계가 잘못된 경우, 비효율적인 동작을 보일 수 있다.
  2. SQL에 대한 일종의 래퍼 역할을 수행하기 때문에, SQL만을 사용하는 것에 비해 성능 저하가 존재한다.
  3. 대부분의 ORM은 통상적으로 사용하는 동작을 지원할 뿐, 복잡하거나 특정 DBMS에 종속된 기능에 접근할 수는 없다. 따라서 복잡한 쿼리 혹은 특정 DBMS만이 가진 기능을 이용하기 위해서는 SQL을 사용해야 한다.

 여러가지 장단점이 존재하기는 하지만, 대부분의 경우 SQL을 직접 관리하여 사용하는 것에 비해 자질구레한 작업이 상당히 감소하며, 객체지향적 언어의 장점을 살려 데이터를 간단하게 관리할 수 있다는 점에서 괜찮은 것 같다. 

 노드 환경에서는 현재 시점 2개의 ORM이 주류를 이룬다.

Sequelize

자바스크립트 + 런타임 기반의 ORM이다. 모델 간 관계를 hasOne, hasMany, belongsTo, belongsToMany 등의 함수를 이용하여 지정하는데, 관계에 의해 발생하는 함수들이 런타임 동작에 의존하기 때문에 타입스크립트 환경에서의 사용이 상당히 제한된다. 굳이 타입스크립트 환경에서 사용해야 한다면 다양한 함수 및 타입을 선언해서 사용해야 하기 때문에, 자바스크립트 환경이 아니라면 굳이 사용할 필요까지는 없는 것 같다.

typeORM

타입스크립트의 데코레이터 기능을 이용하여 동작하는 ORM으로, 데코레이터를 통해 제약조건이나 범위 등을 지정할 수 있다. 개인적으로 Sequelize에 비해 직관적이고 타입 선언이 잘 되어 있어 사용성이 좋다고 느꼈으며, 타입스크립트 기반의 백엔드 프레임워크 중 하나인 nestjs에서는 이 ORM을 기본으로 사용하고 있다.