데이터 모델링의 원칙 등을 공부해서 정리하려다가, 실무적으로 접근할 필요가 있을 것 같아, 최근 웹 개발의 90% 이상을 차지하고 있는(국내 대기업도 이정도일까...?) DDD 설계와 정통적인 방법인 SQL 중심 설계의 차이점을 먼저 정리해보고자 한다.

 

이번 포스팅은 더더욱이 DDD, ORM, DB 설계 등의 매우 깊은 내용을 담고 있기에, 내가 쓰는 내용이 틀릴 확률이 상당히 높다.

그러니 읽으시는 독자 분들께서 틀린 내용이 있다면, 꼭 지적해주셨으면 한다.


DDD(Domain Driven Design)란 무엇인가?

: Domain의 사전적 의미는 '영역, 집합'으로, 비즈니스 Domain에 기반한 애플리케이션의 디자인 패턴을 말한다.

여기서 비즈니스 Domain이란, 유사한 업무의 집합을 의미한다.

 

도메인은 다시 하위의 여러 도메인으로 나누어지곤 하는데, 예를 들면 아래 이미지와 같다. '온라인 쇼핑' 도메인은 '상품',' 주문', '회원'과 같은 하위 도메인으로 나뉘고, 이 중 '주문' 도메인은 다시 '주문자', '주문 상품', '배송'과 같은 하위 도메인으로 나눠질 수 있다.

'온라인 쇼핑' 도메인과 그의 하위 도메인 / 출처 : https://medium.com/myrealtrip-product/what-is-domain-driven-design-f6fd54051590

 

여기서 '집합'이라는 의미에 좀 더 초점을 두고 싶다. 필자가 생각하기에, 기존의 데이터 기반 설계(SQL 기반 설계)와 비교하면, 데이터가 RDBMS의 특징을 잘 살려 어떻게 저장될 지는 설계 과정에서 크게 고려하지 않고,

데이터가 처리되는 단위들 즉, 비즈니스를 애플리케이션 로직으로 어떤 단위로 어떻게 처리할 지를 기준으로 설계하는 방식으로 보인다.

 

DDD는, 기존의 애플리케이션 설계가 비즈니스 Domain에 대한 이해가 부족한 상태에서 설계 및 개발되었다는 반성에서 출발하게 된다. 그렇기에, DDD에서는 기존의 현업->IT로의 일방향 소통 구조를 탈피함으로써, 현업<->IT 라는 쌍방향 커뮤니케이션을 매우 중요하게 생각하는 철학이 담겨 있다.


DDD의 특징

  • 기존에 많이 사용되어 왔던 '데이터' 중심의 접근법을 탈피하여, 순수한 도메인의 모델과 로직에 집중한다.
  • *유비쿼터스(Ubiquitous, 보편적인) 언어를 사용하는 걸 원칙으로 한다.
    이는, 도메인 전문가(현업 전문가)와 소프트웨어 개발자 간의 커뮤니케이션 문제를 없애고, 양쪽 모두가 직관적으로 이해할 수 있으며, 모든 문서와 코드에 이르기까지 동일한 표현과 단어로 구성된 단일화된 언어 체계를 구축해 나가는 과정을 말한다. 이로써, 분석 작업과 설계 그리고 구현에 이르기까지 통일된 방식으로 커뮤니케이션이 가능해지는 것을 지향한다.
  • 소프트웨어 엔티티(Entity)와 도메인 Concept을 가능한 한 가장 가까이 일치시키는 것을 목표로 한다.
    분석 모델과 설계가 다르고, 그로 인해 비즈니스 요구사항과 실제 코드가 다른 구조로 진행되는 것이 아니라, 도메인 모델부터 코드까지 항상 함께 움직이는 구조의 모델을 지향하는 것이 DDD의 핵심 원리이다.
  • DDD의 소프트웨어 아키텍처 측면에서의 핵심 목표는, "Loosly coupling, High cohension" 으로, 애플리케이션 또는 작은 단위의 모듈 각각은 서로간 의존성을 최소화시키고, 응집도는 최대화하는 것이다.

 

*유비쿼터스 언어(Ubiquitous Language) : 도메인에서 사용하는 용어를 코드에 반영하지 않으면, 그 코드는 개발자에게 코드의 의미를 해석해야만 하는 부담을 준다. 보편적인 언어를 사용함으로써, 개발자로서는 코드의 가독성을 높여 코드를 분석 및 이해하는 시간을 절약하고, 도메인 전문가와의 소통의 어려움을 많이 낮춘다.
또한, 도메인 전문가와 소통하며 용어가 정의될 때마다 용어 사전에 이를 기록하여 명확히 정의함으로써, 다른 사람이 이 프로젝트에 합류하여도 공통된 언어를 사용할 수 있도록 도와준다.


 

DDD를 올바르게 설계하고 이행하려면, 다음과 같은 과정을 거치게 된다.

  1. 핵심 도메인을 나누고, 해당 도메인에 집중한다.
  2. 각각의 도메인을 정교하게 구축하고 세분화한다.
  3. 해당 도메인의 문제를 해결할 수 있는 전문가와 적극적인 협업을 한다.

위와 같은 과정에서 다음과 같이 전략적 설계와 전술적 설계의 단계로 나뉘게 된다.

 

DDD의 전략적(Strategic) 설계와 전술적(Tactical) 설계

전략적 설계(Strategic Design)

*Model과 **Bounded Context를 나누는 설계로, 협업을 위한 Ubiquitous Language의 정리도 여기에 포함된다.

현실에서의 개념을 시스템 상의 코드로 구현하기 전, 모델들 사이의 상호작용을 고려하여 인터페이스 등을 정의하거나,
전체적인 흐름을 파악하고 경계를 나누면서 여러 문제를 명확히 이해할 수 있도록 하는 과정이다.

 

전술적 설계(Tactical Design)

시스템 상에서 실제 구현하기 위한 세부 아키텍처를 설계하는 단계로, 코드의 구현과 직접적으로 연관된 부분이며, 
전략적 설계에서 나뉜 경계와 모델 등을 유지보수성과 확장성을 고려하여 코드를 구성하는 등의 작업 과정을 말한다.

데이터 흐름 등을 고려한 세부적인 설계를 수행하고, 구현 과정에서 발생할 수 있는 다양한 문제들을 해결하며,
코드의 유연성과 유지보수성을 개선시키는 과정이 핵심이다.

 

 

*Model(모델) : 도메인에 대한 이해화 복잡성을 해결하기 위해 해당 도메인의 규칙, 개념, 프로세스 등을 포함하는 추상적 개념. 각각의 모델은 서로 간 경계가 확실해야 하며, 개발자와 해당 도메인 전문가가 함께 구축해 나가야 하는 개념.

**Bounded Context(바운디드 컨텍스트) : 같은 용어라도 어떤 도메인인지에 따라 의미가 다르고, 용어가 다름에도 서로 다른 도메인 간 비슷한 역할을 하는 용어들이 있다. DDD의 철학을 위배하지 않으려면, 각 모델은 명시적으로 구분되는 경계를 가짐으로써 서로 섞이지 않아야 하는데, 이렇게 섞이지 않는 특정한 Context 내에서의 완전한 의미를 갖도록 하는 경계를 Bounded Context라고 한다.
(ex) [카탈로그] 도메인에서의 '상품' - [재고 관리] 도메인에서의 '상품' / [회원] 도메인에서의 '회원' - [주문] 도메인에서의 '주문자')

 

 


 

SQL 중심 설계란 무엇인가?

: SQL-DD(SQL Driven Design)이란, RDBMS 측면(인프라적 측면)에서의 데이터베이스 구조와 데이터의 흐름을 중심에 놓고 설계하는 패턴을 말한다.

정통적인 거의 모든 애플리케이션의 전형적인 설계 패턴이었으며, 이는 DB가 올라가는 물리적 서버의 스펙이 가장 좋았기 때문에, 대부분의 비즈니스 로직 처리를 DB 쿼리로서 처리하고자 한 것에서 기인한 걸로 보인다.

 

SQL-DD의 특징

  • 데이터베이스에 대한 전문적인 지식이 있다면, 도메인 모델과 관계형 데이터베이스 간의 일관성을 유지하여 도메인 모델링과 관계형 데이터베이스 설계 간의 간극을 줄이는 것이 가능하며, 이것이 곧 목적이기도 하다.
  • 데이터에 초점을 두고 설계를 하기 때문에, 애플리케이션 로직에서는 객체 자신이 포함하고 있는 데이터를 조작하는 데에 필요한 행동을 정의하여야 한다.
    설계 시, 협력에는 큰 중요성을 두지 않았기 때문에, 과도한 접근자와 수정자가 탄생하게 된다. 이는 결과적으로, 애플리케이션 구현에 있어 대부분의 객체 구조 및 구현이 노출되므로, 캡슐화의 원칙을 위반하게 된다. 따라서, API를 설계하고 공개하는 것도 불가능하게 된다.
  • 추상적인 개념 대신 직관적인 데이터를 위주로 개발이 가능하며, 직관적인 SQL 쿼리 작성으로 빠른 개발이 가능하다.
    But, DB에 대한 낮은 이해로 인해 마구잡이로 개발되어 오히려 서비스 전체의 성능을 악화시키는 요인이 되기도 한다.
  • 역정규화를 통해 도메인 모델과 데이터베이스 구조 간의 일관성을 유지할 수 있으며, 이에 따른 개발 생산성과 성능을 높일 수 있다.
    But, 역정규화를 거듭할수록 중복된 코드의 양이 늘어나거나 데이터 무결성을 저해할 가능성이 높아질 수 있다.
    또한, 데이터의 일관성, 코드 컨벤션의 유지가 역정규화가 이뤄질수록 어려워지기 때문에, 유지 보수의 어려움Scale-out의 어려움, 그에 따른 성능에 악역향을 불러올 수도 있다.
  • 서비스 자체가 동적인 변화가 잦다면, 대응이 매우 어렵다. 예를 들면, '학생', '교사' 이외의 '교환학생', '강사' 라는 도메인이 추가된다면, 새로운 DB 스키마가 필요하며, 그에 따라 모든 쿼리문 및 애플리케이션 로직의 수정이 불가피할 수 있다.

여기까지 잘 읽었다면, 어려운 개념을 소화해 낸 당신 참 대단하다는 말을 해주고 싶다.

아키텍처 관점에서의 모델링이 어떻게 되는 지를 알았다면, 이 모델링 결과가 애플리케이션에서 어떤 것을 통해 활용되는 지를 알아야, 모델링을 더 잘 수행할 수 있을 것이라 생각한다.

그래서 모델링의 결과를 개발 과정에서 '어떤 것'을 통해 활용하는지, 그 '어떤 것'이 무엇인지 확인해보도록 하자!

ORM(Object Relational Mapping)이란 무엇인가?

: 객체-관계 매핑으로, 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑해주는 것을 말한다.
Java 진영에서는 가장 대표적으로 JPA(Java PersistAnce)가 있다.

  • 객체 지향 프로그래밍(특히 Java)은 클래스를 사용하고, 관계형 데이터베이스는 테이블을 사용한다.
    이에 따른, 객체 모델과 관계형 모델 간 불일치가 필연적으로 존재하게 된다.
    이에 대한 해결책으로 나온 것이 ORM으로, 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하여
    이러한 불일치 문제를 해결한다.
  • Persistant API라고도 하는데, 여기서 말하는 Persistant(영속적인) 즉, Persistance(영속성)란, 다음과 같다.
    • 영속성(Persistance) : 데이터를 생성한 프로그램이 종료되더라도, 그 데이터는 사라지지 않는 데이터의 특성을 의미.
  • 장점)
    • 객체 지향적인 코드로 인해 더 직관적이고 비즈니스 로직에 더 집중할 수 있게 도와줌
      => SQL 쿼리가 아닌, 직관적인 코드(메서드)로 데이터를 조작하게 됨.
    • 재사용 및 유지보수의 편리성이 증가함
      => ORM은 독립적으로 작성되어 있으며, 해당 객체들을 재활용할 수 있음. (객체의 특징)
    • DBMS에 대한 종속성이 줄어듦
      => DBMS에 따른 자료형의 종속성에서 많이 벗어날 수 있으며, 이기종 DB 사용가능.
  • 단점)
    • 100% ORM만으로 서비스를 구현하기는 어려움
      => 설계부터 매우 신중해야 하기 때문에, 100% 완벽한 설계는 존재할 수가 없으며, 프로젝트의 복잡성이 커질 경우 난이도 또한 올라가게 됨.
    • 프로시저가 많은 시스템에서는 ORM의 객체 지향적인 장점을 활용하기가 어려움
      => 이미 프로시저가 많은 시스템에서는, 해당 프로시저를 구현하는 데에 필요한 객체들을 다시 설계하고 바꿔야 하므로, 생산성 저하 및 리스크가 발생할 수 있음.

 


SQL Mapper란 무엇인가?

: 객체와 관계형 데이터베이스의 데이터를 개발자가 작성한 SQL로 매핑시켜주는 프레임워크.

대표적으로 MyBatis 라는 프레임워크가 있다.

  • ORM과 동일한 기능으로 보이나, 가장 큰 차이점은 이 프레임워크에서 객체와 관계를 매핑하여 사용하기 편한 메서드 등을 제공해주는 것이 아닌, 개발자가 직접 작성한 SQL문의 결과와 객체의 필드를 매핑하여 데이터를 객체화 시킨다는 점이다.
  • 장점)
    • JDBC를 사용했을 때 발생하는 불필요한 코드들을 줄일 수 있다. (Connection 관리, Checked Exception 처리 등)
    • DAO로부터 SQL문을 분리함으로써, 코드의 간결성 및 유지보수성을 향상할 수 있다.
    • DBMS에 대한 지식이 해박하다면, 쿼리를 직접 작성하여 그대로 적용할 수 있으므로, 복잡한 JOIN, 튜닝 등을 좀 더 수월하게 작성이 가능하다.
  • 단점)
    • SQL문을 직접 모두 작성해야 한다. 
      => DB 설정 변경 또는 DBMS가 바뀔 시, 수정할 부분이 너무나도 많아지게 된다.
    • 객체 모델과 관계 모델을 각각 따로 개발해야 함으로써, 유지보수성이 하락된다.
    • DBMS에 대한 종속성이 매우 크므로, 이기종 DB를 사용하는 것 자체가 리스크가 된다.

우리 회사 또는 우리 팀이 개발한 프로젝트에서 지금 사용하고 있는 아키텍처는 뭐지?

약 8년 전, 실제 Spring, JPA 강의의 대가 김영한 님이 OKKY라는 IT 커뮤니티 사이트에 썼던 글이기도 하고, 그에 대한 댓글들에서 많은 인사이트들을 얻을 수 있는 것 같아 아래 글을 첨부한다. 여기에서 'fender' 님의 댓글이 인상깊어서 가져와본다.

Q. 현재 개발 중인 프로젝트에 대해 '퇴사 처리'는 어떻게 해야 하지?

A1. 회원 테이블 또는 그와 관련된 레코드를 찾아 이 컬럼값을 바꾸면 되지!

=> 해당 프로젝트는 데이터베이스 중심적(SQL-DD)으로 설계되고 구현되고 있다는 것에 대한 반증일 가능성이 매우 높다.

A2. 회원 클래스를 가져와서 이 속성을 이렇게 바꾸면 되지!

=> 해당 도메인 클래스의 인스턴스에 대한 영속성을 확보한다는 측면에서 JPA와 같은 본격적인 ORM 라이브러리 도입이 자연스러운 선택이 되는 프로젝트일 가능성이 높다.

 

 

https://okky.kr/questions/286812

 

OKKY - ORM의 사실과 오해

ORM의 사실과 오해 http://okky.kr/article/286531 개시물에 댓글을 해주신 자유로운 새님의 글에 대해 질답 하는 형식으로 한 말씀 올리겠습니다. 먼저 은탄환은 없다는 것을 말씀드립니다. ORM은 절대 만

okky.kr


그래서 무엇이 기본으로 지향해야 하는 아키텍처일까?

현대 사회에서의 웹 개발자라면 DDD가 더 옳은 방향이라고 생각한다. 대부분의 웹 개발이 Java로 이루어지며, 이 'Java'라는 언어 자체가 '객체 지향'이다. 그런데, RDBMS는 '관계 지향'이며, 데이터를 중심으로 잘 정규화하여 '저장'하는 것에 기본적인 의미를 두고 설계되었기 때문에, 이 둘이 서로 지향하는 방향이 약간 다르다.

인프라 엔지니어의 입장에서 보면, DB 서버는 Scale-out이 매우 어렵고 신경 써야할 것이 매우 많은 반면, APP 서버는 Scale-out이 비교적 쉽고, 신경 써야할 것이 DB 서버에 비해 상당히 적다.

따라서, 데이터는 최대한 가볍게 꺼내 쓰고 가볍게 저장하며, 이를 기반으로 APP 서버가 열심히 일하여 비즈니스 로직을 처리하도록 개발하는 것이, 기업의 비용을 절감하고, 추후의 인적 리소스를 확보하는 데에 있어서도 더 옳은 방향이라고 생각한다.

 


참고

https://happycloud-lee.tistory.com/94

 

DDD 핵심만 빠르게 이해하기

마이크로서비스의 설계 방법론인 DDD(Domain Driven Design)에 대해 제가 가진 지식과 그간의 경험을 기반으로 정리하였습니다. 이 글을 읽기 전에 먼저 일하는 방식 변화를 이끌고 있는 애자일, 마이

happycloud-lee.tistory.com

https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd

 

DDD(Domain Driven Design) - Incheol's TECH BLOG

이벤트 소싱과 항상 함께 알아두어야 할 개념으로 CQRS가 있으며 간단히 설명하면 커맨드와 쿼리의 책임을 분리하자는 것이다. 커맨드는 일반적인 디비 기준으로 상태를 변경하는 C,U,D와 같은 메

incheol-jung.gitbook.io

https://youwjune.tistory.com/38

 

DDD 설계 vs SQL 중심 설계

1. DDD란? DDD(Domain Driven Design : 도메인 주도 설계)란? 도메인 패턴을 중심에 놓고 설계하는 패턴이다. 즉, 도메인 간의 상호작용이 설계의 중심이 된다. 도메인이란, 소프트웨어로 해결하고자 하는

youwjune.tistory.com

https://velog.io/@cv_/DDD-vs-SQL-%EC%A4%91%EC%8B%AC-%EC%84%A4%EA%B3%84-%EC%B0%A8%EC%9D%B4

 

DDD vs SQL 중심 설계 차이

DDD(Domain-Driven Design)와 SQL-DD (Structured Query Language-Driven Design)는 소프트웨어를 개발하는 여러 방법론중 일부이다. 두 방식의 차이는?

velog.io

https://gmlwjd9405.github.io/2019/02/01/orm.html

 

[DB] ORM이란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

https://jongsky.tistory.com/15

 

ORM vs SQL Mapper

1. 글을 작성하게 된 이유 Rest API를 만들면서 생겨난 이슈사항이다. FastAPI를 이용해 request가 왔을 때 response를 해주는 Rest API를 만들고 있었다. response를 위해서는 기존에 만들어진 db(mysql)에서 데

jongsky.tistory.com

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기