4주차 개념 스터디

4주차 개념 스터디

ORM의 연관관계 매핑

첫인상은 mySQL의 join과 비슷했다. 카페 테이블, 사이트 회원 테이블이 있고 회원 테이블의 속성 중 '소속중인 카페의 id' 속성이 있을 때 join을 이용하여 해당 id를 가지는 카페의 자세한 속성을 확인할 수 있듯이 말이다. 이렇게 테이블끼리 관계를 맺을 때 이런 경우 외에도 몇가지 종류가 더 있다고 한다.

이해를 위해 몇 가지 정리하자면

외래 키 라는 게 있는데 위에서 예로 든 '소속중인 카페의 id' 같이 관계형 DB에서 한 테이블의 필드 중 다른 테이블의 행을 식별할 수 있는 키 를 뜻한다.

라는 게 있는데 위에서 예로 든 '소속중인 카페의 id' 같이 관계형 DB에서 를 뜻한다. 단방향은 한쪽만 다른 쪽을 참조하는 것이고 양방향은 양측 모두 서로를 참조하는 것이다.

DB에서는 한쪽만 외래키를 가져도 join을 통해 양쪽 참조가 모두 가능하지만 객체의 경우에는 참조용 필드가 있는 경우에만 다른 객체 참조가 가능하다. 즉 ORM에서 양방향 참조는 엄밀하게 말하면 존재하지 않으나 양쪽 모두 참조용 필드를 가져서 양방향 관계처럼 사용할 수 있다. 복잡함을 피하기 위해서 필요하지 않는 이상 양방향 참조를 피하는게 좋다.

One-to-One

말 그대로 1대1이다. 학생과 개인 사물함이 있을 때 학생은 사물함 1개만을 소유할 수 있고 사물함 또한 학생 1명에게만 소유될 수 있듯이 말이다. 단방향일 경우에는 학생 테이블이 외래키를 갖고 있다면 학생 테이블이 사물함 테이블을 참조하는 것이다. 만약 사물함 테이블에도 외래키를 가진다면 이는 양방향이 되는 것이다.

Many-to-One

회원과 팀 테이블이 있고(회원수 > 팀) 회원은 1개의 팀에만 속한다고 하자. 그리고 회원은 팀을 참조할 수 있지만 팀은 회원을 참조할 수 없다. 회원 수가 팀 수보다 많으니 같은 팀을 참조하는 학생들이 2명 이상일 것이다. 때문에 회원 대 팀은 N-1, 단방향 연관관계가 이루어지고 'N'이 외래키를 관리하는 형태가 된다. 이 관계에서는 회원이 연관관계의 주인이 된다.

One-to-Many

이거는 Many-to-One을 반대로 뒤집은거 아니냐?라는 의문이 처음에 들었다. 이것이 위와 구분되는 기준은 연관관계의 주인이 누가 되는가이다. 위에서는 N측이 주인이었지만 여기서는 1측이 주인이 된다. DB 입장에서 외래키는 반드시 'N'측에서 관리를 하는데 이런 형태는 뭔가 이상하지 않은가? 실제로도 실무에서 해당 연관관계는 잘 사용되지 않고 양방향 N:1을 사용한다고 한다.

Many-to-Many

고객 테이블과 상품 테이블이 있다고 하자. 여러 고객이 같은 상품을 주문할 수 있고 한 상품이 여러 고객한테 판매될 수 있다. 관계형 DB에서는 정규화된 2개의 테이블로 N:N관계를 표현할 수 없기에 조인 테이블을 사용하는데 여기에는 고객과 상품을 식별할 수 있는 키가 담긴다. 하지만 객체의 경우에는 조인 객체를 따로 두진 않는다. 고객은 상품을, 상품은 고객을 참조할 뿐이다.

ORM의 N+1 문제

글 처음에 카페 테이블, 사이트 회원 테이블이 있고 회원 테이블의 속성 중 '소속중인 카페의 id' 속성이 있을 때_라는 예시를 들었다. N명의 회원이 있다고 할 때, N명의 정보를 가져오려면 몇 개의 쿼리를 사용해야 할까? 당연히 *_SELECT * FROM users**같이 쿼리 하나만 사용하면 되는 것 처럼 보인다. 그러나 *'소속중인 카페의 id' 때문에 회원 한명당 카페 테이블에서 데이터를 가져와야 하므로 실제 N+1번의 쿼리가 발생하게 되는 것이다. 이를 해결하기 위해 join을 사용하거나 로딩시 참조해야 할 정보를 미리 명시하는 eager loading등을 사용한다.

객체 지향이란

프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법

객체는 물건이다. 빗자루, 샴푸, 옷걸이 등 일상생활에는 물건이 정말 많이 존재한다. 그리고 이러한 물건은 각자의 쓰임새가 있다. 그리고 바지, 셔츠, 치마 등을 '옷'이라는 카테고리로 묶을 수 있듯이 여러 물건을 포함하는 상위 개념의 물건이 존재한다. 지향 _어떤 목표로 뜻이 쏠리어 향함_이라는 뜻을 가진다. 그러므로 객체의 특성을 코드로 변환한다면 이것이 객체 지향 프로그래밍이 될 수 있겠다.

객체 지향이 가지게 되는 장점은

코드의 재사용을 지향하므로 이미 만들어진 코드를 가져다가 사용하거나 객체의 기능을 상속받을 수 있다. 때문에 생산선이 증가하게 된다.

어떤 프로그램을 모델링할 때 이를 하나의 절차로 생각하는 것보다 객체간의 상호작용으로 생각하는게 묘사할 때 수월하다.

캡슐화를 사용해 실제 구현 부분을 외부에 노출되지 않도록 하여 정보 은닉이 가능하기 때문에 보안성이 높다.

리팩터링

결과의 변경 없이 코드의 구조를 재조정함

사용자에게 보여지는 것들은 그대로이나 어플리케이션이나 프로그램의 내부 구조를 개선하는 것이다. 본인이 학교서 준 과제를 수행할 때 우선은 주어진 결과값이 어떻게든 나오도록 코드를 작성하였다. 하지만 '어떻게든' 작성하였기 때문에 코드가 굉장히 지저분하고 성능이 저하될 요소가 있었다. 물론 아직 큰 규모의 코드는 경험해본적이 없어 체감은 되지 않았지만 만약 큰 규모의 프로젝트에서 '어떻게든'작성한 코드는 성능에 있어 굉장히 문제가 많을 것이다. 그렇기에 성능향상과 비용절감을 위해 내부 구조를 개선할 필요가 있는 것이다.

원리나 방법에 대한 내용은 https://nesoy.github.io/articles/2018-05/Refactoring 을 참고하자

테스트코드

테스트 코드의 궁극적 이유는 당연히 좋은 코드(잘 작동, 깔끔한)를 얻기 위함이다. 테스트 코드를 따로 만들면 여기서 시간이 더 지체되는게 아닌가라고 생각할 수 있지만 테스트 코드 유무에 따른 테스트 과정을 보면 그런 생각은 사라질 것이다.

테스트 코드 없이 웹 어플리케이션을 테스트하려고 하면 <서버 동작 -> 필요 데이터 DB에 입력 -> 브라우저로 서버에 접속하여 관련 메소드 동작하게끔 요청 -> DB 데이터 정리> 같은 과정을 거친다. 만약 테스트 코드들 이용하여 테스트를 한다면 <테스트 코드 실행 -> 결과 확인> 의 과정만 거치면 되는 것이다. 테스트는 여러번 이루어지므로 시간 단축에 큰 도움이 된다.

TDD(테스트 주도 개발, Test-Driven Development)

개발을 할 때 테스트를 염두에 둔 개발한다는 의미이다.

그림에서 확인할 수 있듯이 테스트 주기가 짧아지기 때문에 설계 문제로 인한 오류를 개선하는 속도를 훨씬 빠르게 할 수 있게 된다. 또한 특정 단위로 명확한 기능과 구조를 설계할 수 있으므로 객체지향적이다. 때문에 코드의 재사용성도 증가하게 된다. 그리고 설계 시 문제를 빠르게 찾아낼 수 있기 때문에 설계 수정시간도 줄일 수 있다.

참고자료

DogHujup / https://ocwokocw.tistory.com/

[기본기를 쌓는 정아마추어 코딩블로그] / https://jeong-pro.tistory.com/95

진짜 개발자 / https://galid1.tistory.com/783

소프트웨어로 안전한 세상을 꿈꾸다 / https://m.blog.naver.com/suresofttech/221569611618

from http://sepang2.tistory.com/15 by ccl(A) rewrite - 2021-08-27 04:00:03

댓글