NestJS

ORM에 의존해선 안되는 이유

25G 2023. 11. 6. 21:26

ORM

ORM (Object-relational mapping)은 객체와 데이터베이스 시스템을 연결(맵핑)해주는 라이브러리다. 세상엔 다양한 데이터 베이스 시스템이 있고 이를 다양한 방식으로 연결해야 하는데, ORM은 이렇게 둘 사이 (소스와 애플리케이션)의 연결을 도와주는 가교 역할을 한다. 따라서 많은 개발자들이 ORM과 데이터베이스의 마이그레이션을 편리하게 하기 위해 사용한다.

왜 쓰지 말아야 하는지에 대해 논의하기전에, 먼저 ORM의 장점을 살펴보자.

  • 중복 코드 방지
  • 다른 데이터베이스로 쉽게 교체 가능
  • 여러 테이블에 쉽게 쿼리를 날릴 수 있음
  • 인터페이스를 작성하는 시간을 아껴 비즈니스 로직에 집중할 수 있음

ORM에 의존해선 안된다. ORM보다 SQL을 더 중요하게....

기존에 나와있는 ORM만해도 종류나 가짓수가 엄청나게 많다. 그 모든 ORM을 이해하고 사용하는 것은 말도 안되는 일이다. 하나의 ORM에 의존하다가 다른 ORM을 써야 하는경우에는 또 공부하고 문서를 들여다보는등의 비용이 많이든다.
하지만 SQL을 명확히 알고 있다면 DB를 다루는 기본적인 능력이 상향되기 때문에 ORM을 바꿔쓰더라도 크게영향을받지 않고 사용 할 수있다.

ORM이 만능은 아니다.

일부 쿼리는 ORM 작업으로 표현할 수 없다. 이러한 쿼리를 생성하는 경우에는 SQL 쿼리를 직접생성하는 작업으로 회귀해야 한다. 이는 ORM을 사용하는 와중에도 코드베이스에 여전히 하드 코딩된 쿼리가 존재할 수 있다는 것을 의미한다. 이러한 프로젝트를 개발하는 개발자는 ORM이나 SQL구문 모두를 알아야 한다.

ORM으로 표현할 수 없는 쿼리에는 쿼리에 서브쿼리가 포함된 경우다.

SELECT *
FROM item
WHERE
id NOT IN
(SELECT item_id FROM ingredient WHERE dish_id = 2)
AND id IN
(SELECT item_id FROM ingredient WHERE dish_id = 1);
이 쿼리는 앞서 언급한 ORM을 사용하여 명확하게 나타낼 수 없다. 이러한 상황에 대처하기 위해, ORM에서는 쿼리인터페이스에 로우 쿼리 문자열을 주입하는 기능을 제공하는 것이 일반적이다.

Sequelize의 경우에는 로우 쿼리문을 실행하는 .query()메소드를 제공한다. Bookshelf와 Objection ORM을 사용하면, 로우 knex 객체에 엑세스할 수 있다. Knex 객채에는 로우 쿼리를 실행하는 .raw() 메소드도 있다. 어쨌건 간에, 여전히 특정 쿼리를 사용하기 위해서는 SQL을 이해해야한다.

로우쿼리보다 비용이 많이든다.

ORM으로 쿼리문을 작성하면 복잡할 수록 로우쿼리보다 오버해드가 많이 발생해서 비용이 많이 든다고 합니다. 그렇기 때문에 SQL을완벽하게 이해하고 있다면 쿼리빌더를 애용하는것이 타협점을 찾는 좋은 방법이지 않을까요?

참고 블로그