ORM

양치는 하셨나요·2024년 9월 2일
0
post-thumbnail

또 나타났다.. 처음 보는 단어!

ORM… 일단 CS에서 O로 시작하면 객체(Object)인 경우가 많았는데 이번에도 그런가? 한 번 자세히 조사해본다.

사전 개념

영속성(Persistence)

개념

생성된 데이터가 해당 데이터를 생성한 프로그램을 종료하더라도 사라지지 않는 데이터의 특성

→ 영속성이 없다면 프로그램을 종료할 때 데이터가 사라진다. 이를 막기 위해 파일시스템, DB 등을 이용해 데이터를 저장해 영속성을 띄게 하여 데이터를 보존한다.

영속성 객체(Object Persistence)

위에서 말했듯 파일 시스템, DB 등을 이용해 영속성을 띄게 하는데 이런 영속성을 부여하는 시스템을 사용할 수 있도록 한 것이 영속성 객체이다.

저장 방법

  • JDBC(Java에서 사용한다. JDBC에서 제공하는 API를 이용해 DB에 접근한다. )
  • Spring JDBC (스프링 개발 시 사용하는 JdbcTemplate가 이것이다. )
  • Persistence Framework (Ex. JPA, Hibernate, Mybatis 등이 있다. )
    • JDBC의 복잡하거나 번거로운 작업 없이 간단하게 DB와 연동되는 시스템을 빠르게 개발할 수 있게 해주며 안정적인 구동을 보장한다.
    • 결국 개발자가 하나하나 다 작성하기 어려운 것을 대신 해주는 것이다. Spring에서 JPA를 사용해 간단한 함수를 이용해 DB에 접근 할 수 있는 것도 이런 프레임워크 덕분이다.

Persistence Layer

  • 프로그램 아키텍쳐에서 데이터의 영속성을 부여해 주는 계층.
  • JDBC로 직접 구현도 가능하지만 보통 Persistence Framework를 이용한 개발이 많이 이뤄진다고 한다.

ORM(Object-Relational Mapping)

개념

객체 관계 매핑(Object-relational mapping; ORM)은 데이터베이스와 객체 지향 프로그래밍 언어 간의 호환되지 않는 데이터를 변환하는 프로그래밍 기법이다. 객체 지향 언어에서 사용할 수 있는 "가상" 객체 데이터베이스를 구축하는 방법이다. 객체 관계 매핑을 가능하게 하는 상용 또는 무료 소프트웨어 패키지들이 있고, 경우에 따라서는 독자적으로 개발하기도 한다.

위키백과에선 위와 같이 정의되어 있다. 이를 뜯어 살펴보면 아래와 같이 나눌 수 있을 것 같다.

  • 데이터베이스와 객체지향 프로그래밍 사이에서의 언어의 차이를 해결해주는 것이다.
  • OOP에서 사용 가능한 가상 객체로 데이터베이스를 구축한다.
  • 이런 매핑을 가능하게 하는 다양한 패키지들이 있고 경우에 따라 독자적 개발도 요한다.

즉, RDB와 객체지향 언어에 구조적 차이가 있기 때문에 이를 해결하기 위해 등장한 매핑 기법인 것이다.

→ Java는 그 자체로는 영속성을 띄지 않아 영속성을 부여하기 위해 영속성 객체를 생성해 데이터를 저장할 수 있게 하는데 그 중 RDB(관계형 데이터베이스)와의 연결 시 언어의 차이로 인한 문제가 있기 때문에 이를 해결하고 서로 매핑 시켜주는 것이 ORM이다.

장점

  • 객체지향적인 코드로 더 직관적이게 코드 작성이 가능하다.
    • RDB의 절차적이고 순차적인 접근이 아닌 객체지향적 접근으로 생산성이 증가한다.
    • 비즈니스 로직에 집중한 개발이 가능하다.
    • 선언문, 할당, 종료 등과 같은 부수적 코드가 급격히 줄어든다. → 코드의 가독성이 증가한다.
  • 재사용성 및 유지보수의 편리성 증가
    • ORM은 독립적으로 작성되어 있기 때문에 해당 객체의 재활용이 간편하다. → 가공된 데이터를 컨트롤러와 뷰를 이용해 디자인 패턴을 견고하게 다지는데 유리하다.
    • 매핑 정보가 명확하여 ERD의 의존도가 낮아진다.
      • ERD(An Entity Relationship Diagram): 시스템의 엔티티가 무엇에 어떤 연관관계가 있는지를 나타내는 다이어그램. 시스템의 데이터적 관점에서의 흐름을 볼 수 있다.
  • DBMS에 대한 종속성이 줄어든다.
    • 대부분의 ORM은 DB에 종속적이지 않다.
      • 구현 방법에 더불어 많은 부분에서 자료형 타입까지 유효하다는 것.
    • 개발자는 객체에 집중해 극단적인 DBMS 교체 같은 큰 작업에도 적은 리스크와 시간이 소요된다.
    • Java에선 equals, hashCode의 오버라이드 같은 자바만의 기능을 이용 가능하다.

단점

  • 완벽한 ORM만으로 서비스를 구현하기는 어렵다.
    • 사용의 편의만 바라보고 접근하면 안된다. 신중하게 사용해야 한다.
    • 프로젝트의 복잡성이 증가하면 ORM 구현 난이도가 증가하기 때문이다.
    • 구현이 잘못되면 속도 저하를 넘어서서 일관성이 무너지는 문제점이 생긴다.
      • 일관성은 RDB 뿐 만 아니라 데이터를 저장하는 곳에서는 매우 중요한 문제이기 때문이다.
  • 프로시저가 많은 시스템에서는 ORM의 객체지향적 관점을 활용하기 어렵다.
    • 프로시저: DB에 대한 일련의 작업을 정리한 절차를 RDB 관리 시스템에 저장한 것.
    • 이런 프로시저를 다시 객체로 바꿔야 하기 때문에 생산성 저하를 비롯한 리스크가 발생할 수 있다.

객체-관계 간 불일치

이 또한 단점 중 하나로 객체 지향과 RDB의 발전 방향의 차이로 인해 발생했다.

세분성(Granularity)

  • 경우에 따라서 데이터베이스에 있는 테이블 수보다 더 많은 클래스를 가진 모델이 생길 수 있다.
    • ex) 어떤 사용자의 세부 사항에 대해 데이터를 저장
  • 객체지향 프로그래밍에서는 코드 재사용과 유지보수를 위해 Person과 Address라는 두 개의 클래스로 나눠서 관리가 능 그러나, 데이터베이스에는 person이라는 하나의 테이블에 사용자의 세부사항을 모두 저장할 수 있음 → 이 상황에서 Object는 2개, Table는 1개가 되어 개수가 달라지는 것

상속성(Inheritance)

  • RDBMS는 객체지향 프로그래밍 언어의 특징인 상속 개념이 없다.

일치(Identity)

  • RDBMS는 'sameness'라는 하나의 개념을 정확히 정의하는데, 바로 기본키를 이용하여 동일성을 정의한다.
  • 그러나 자바는 객체 식별(a == b)과 객체 동일성(a.equals(b))을 모두 정의
  • 즉, RDBMS에서는 PK가 같으면 서로 동일한 record로 정의하지만, Java에서는 주소값이 같거나 내용이 같은 경우를 구분해서 정의

연관성(Associations)

  • 객체지향 언어는 객체 참조를 사용하는 연관성을 나타내는 반면, RDBMS는 연관성을 ‘외래키’로 나타낸다.
  • ex) 자바에서의 객체 참조는 방향성이 있기 때문에, 양방향 관계가 필요한 경우 연관을 두 번 정의해야 함 → 서로 Reference를 가지고 있어야 함
    • 그러나, RDBMS에서는 FK와 Join으로 자연스럽게 방향성이 없는 연결이 이루어짐

탐색(Navigation)

  • 자바와 RDBMS에서 객체를 접근하는 방법이 근본적으로 다름
  • 자바는 그래프 형태로 하나의 연결에서 다른 연결로 이동하며 탐색
  • ex) user.getBillingDetails().getAccountNumber()의 형식
    • 그러나 RDBMS에서는 일반적으로 쿼리 수를 최소화하고 JOIN을 통해 여러 엔티티를 로드하고 원하는 대상 엔티티를 선택하는 방식으로 탐색

Raw SQL

개념

위에서 말한 객체-관계 불일치의 여러가지 문제로 인해 SQL을 안정적으로 사용할 수 없는 상황이 생긴다고 하면 우리는 SQL 쿼리문을 직접 작성해서 명확하게 해 줄 필요가 있다. 이때 사용하는 것이 Raw SQL이다.

장점

이름 그대로 SQL 쿼리를 그대로 작성하는 것으로 해당 DB에 가장 적합한 쿼리문을 작성해 줄 수 있기 때문에 효율적으로 데이터를 처리할 수 있다.

N+1 문제를 비롯한 대량의 데이터 처리 문제가 생길 때에도 효과적으로 데이터를 처리할 수 있다.

  • N+1 문제는 추후 JPA 게시글에서 다뤄보도록 한다. 간단하게 이야기 하자면 Entity가 N:1의 관계를 가지고 있을 때 이의 데이터를 조회할 때 단순히 1번 접근 하는 것이 아니라 N+1 만큼 접근해야 해서 데이터를 가져오지 못하게 되는 문제이다.

단점

하지만 Raw SQL은 기존 애플리케이션에서 쓰는 언어가 아닌 RDB의 쿼리문을 사용하는 것이므로 코드의 가독성이 떨어지고 객체지향의 장점을 잃어버릴 수 있어 유지보수의 효율성도 떨어질 수 있다.

또한 DB의 쿼리문인 만큼 DB에 종속적일 수 밖에 없다.

추가 사항: ODM

개념

Object Document Mapper로 NoSQL의 DB를 이용할 때 사용하는 것이다.

NoSQL(Not Only SQL)

관계형 DB 뿐 만 아니라 다양한 DB를 명칭한다. 빅데이터를 다룰 때 RDBMS만으로는 트래픽을 감당하기 어려워저 이를 해결하기 위해 탄생한 것이다.

  • MongoDB: 가장 많이 사용되는 NoSQL DBMS 중 하나이다.

특징

  1. Join이 없으므로 Join이 필요 없도록 데이터 구조화가 필요
  2. 다양한 종류의 쿼리문을 지원(필터링, 수집, 정렬, 정규표현식 등)
  3. 관리의 편의성
  4. 스키마 없는(Schemaless) 데이터베이스를 이용한 신속 개발. 필드를 추가하거나 제거하는 것이 매우 쉬워짐
  5. 쉬운 수평 확장성
  6. 인덱싱 제공
  • ORM과 ODM은 근본적으로 역할이 같다.
    하지만 ORM은 SQL을 위해, ODM은 NoSQL을 위해서 존재한다고 생각하면 편하다.

결론

데이터를 저장하고 그것이 프로그램의 종료에 영향을 받지 않는 특성을 영속성이라고 한다.

Java와 같은 객체지향 언어에 영속성을 부여하기 위해 ORM을 이용한다.

만약 ORM으로 작성이 힘든 경우 Raw SQL로 직접 쿼리문 작성도 가능하다.

객체지향 언어와 RDB에서 데이터를 바라보는 방법이 서로 다르기 때문에 여러 문제가 있으니 신중히 사용해야 한다.

profile
프로그래밍을 잘하고 싶어요..

0개의 댓글