Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Note

합집합,교집합은 순서가 다르다고 결과가 달라지지 않습니다. ( 드라이븐 시작조건에 의해 성능이 달라질순 있어도 - 실행계획에의해 순서에따라 성능이 다를수 있습니다.  )

하지만 차집합은 빼는것이기때문에 교환법칙이 성립되지않기때문에 순서에 유의합니다.

교환법칙

A +B = B + A : 같음으로 교환법칙 성립

A - B = B - A : 같지 않다.

...

다중DB 환경설정 에서 두가지 DB를 설정하여 운영하는 방법을 정리하였으니 참고하세요 

여기서 윈도우란 의미는 OS윈도우와 상관없으며, 특정 구간을 ROW단위로 중간집계할수 있는기능으로

논리적인 방식으로 윈도우 파티션되었다라고 이해하면 될것같습니다.


Group ByPARTITION BY
SELECT t.address,count(*) FROM address t GROUP BY addressSELECT name,address,COUNT(*) OVER(PARTITION BY address) FROM address

자르기 기능과 동시에 집계기능이 수행되어 원래의 데이터에서

요약 집계 처리가 됩니다.

GroupBy와 비교를 하면, 집계기능을 사용하기위해 요약처리가 안되고

레코드수를 그대로 유지하면서 원하는 집계수를 볼수가 있으며

자르기 기능만 수행되었다라고 보시면됩니다.

이해를 돕기위해 색상으로 데이터를 사각형 분리를하였으며

논리적으로 파티션 혹은 자른 사각형이 윈도우같다고 하여 윈도우처리

되었다라고 표현됩니다.


나이 많은순으로 랭크를 내고자 한다고하면, 윈도우함수인 RANK()를 활용하면 간단하게 구할수있습니다.

이 기능은 Group BY및 서브쿼리와 결합하여 구현하거나 어플리케이션내에서 랭킹을 부여하는

방법으로 구현 할수도 있겠으나,DB가 지원한다고 하면 윈도우함수 사용이 권장됩니다.


postgresql기준으로 더 자세한 윈도우함수 종류와 사용방법을 살펴볼수 있습니다.

https://www.postgresql.org/docs/10/static/functions-window.html

...

Code Block
languagejava
themeEmacs
titleRank수행하기
	public void RankTest() {		
	     int[] score = {Integer.MIN_VALUE};
	     int[] no = {0};
	     int[] rank = {0};	
	     List<AddressAgeRank> ageRankList =  
				addressRepo.findByAgeBetween(10, 90).stream()
				.sorted((a,b) -> b.getAge() - a.getAge() )
				.map(p -> {
		             ++no[0];
		             if (score[0] != p.getAge()) rank[0] = no[0];
		             return new AddressAgeRank(p.getName(),score[0] = p.getAge(),  rank[0] );					
				})
				.collect(Collectors.toList());
	     
	     ageRankList.forEach(item ->{
	    	 System.out.println(item.toString());	    	 
	     });	    
	}
Expand
title결과



Note
title결론ORM은 전통적인 방식에서 대안인가?

ORM은 쿼리를 모르는 사람이 편리하게 사용할수 있는 툴일까? 로 시작하여

비교적 쉬운 데이터 모델은 ORM을(SQL PART-A) 통해 무난하게 학습진행되었지만

제가 원하는 진정한 변환은 SQL-PART2였으며 여기서 문제가 발생하였습니다.


이것의 변환을 위해 DB학습을 더해야했으며 표준적이지 않지만 해결방법을찾아야했습니다.

ORM은 DB를 이해하고 OOP로 변환하고 일치시키려는 컨셉을 가지고 있기때문에

DB와 OOP 연마를 함께해야하며 평균이상 더 해야한다란 결론에 도달하였습니다

SQL-PART B부분이 자연스럽게 ORM으로 표현이 가능하다라고 하면 ORM의 고급부로 더 진행하려고 하였지만 잠시 멈춘상태입니다.

SQL 의 CASE문 UNION, 윈도우함수를 통한 집계등 집계를 위해 선언형 인 SQL문을

ORM(JPA) 사용하여 표현하려 하였지만 , 표준적이지 않고 실제 사용하려던 쿼리방식에서 불일치가 발생하며 뭔가 어색합니다.

DB를 다루는 방식인 비지니스모델을 스키마와 엔티티에 녹여내고,여러 관계를 포함 제약조건걸고 중복제거 정규화 하는과정등

OOP의 설계 과정과 불일치 합니다. 

ORM은 쿼리를 모르는 사람이 편리하게 사용할수 있는 툴일까? 로 시작하였지만 여기서 생각의 전환이 발생하였습니다.

ORM은 DB를 더 잘 이해하고 OOP로 일치시키려는 컨셉을 가지고 있기때문에,  DB와 OOP 연마를 평균이상 더 해야합니다.


그러고도 복잡한 쿼리에대한 성능문제 예를 들면 N+1의 문제를 해결해야합니다.

ORM을 사용하기위해서는 개발 패러다임이 바뀌어야하고 더 높은 수준의 개발자가 있어야한다는것이 저의 생각입니다.

ORM N+1 문제를 검색하면, 엄청난 량의 각기 다른문제를 검색할수 있으며

이것을 해결하는 표준적인 방법이 없으며  ORM을 사용하는 각각의 프레임워크마다 해결방식이 다릅니다.


ORM에 도전하기위해서는 기존개발 패러다임이 바뀌어야하고 다음과같은 더 고난이도의 해결해야할 과제가 있음을 알게되었습니다.

  • 데이터 모델을 OOP로 완벽하게 표현하는것은 불가능하다. ( DB의 관계를 OOP의 상속으로 모두 해결할수 없습니다. )
  • 데이터 마이그레이션은 항상 일어나는일이며, 이에대한 해결방식을 ORM 솔류션이 제공해야한다.
  • DB 성능의 책임이 어플리케이션쪽에 어느정도 있으며, 결국 분산 처리라는 과제를 어플리케이션도 함께해야한다.
  • 전통적인 CRUD 개발방법은 어느정도 안정성검증및 문화가 형성되어있으며, NOSQL이 이것을 모두 대처하는것은 아니며 여전히 중요합니다.
  • ORM과 별개로 웹개발에서 OOP 가 실종되어간다. ORM은 DbRelation을 OOP로 표현하려는것이 본질이다.  OOP는 학습하지 않으면서 ORM이 쉬운길이라 생각하고 선택하려한다. 이것이 안티패턴이다.
  • OOP 를 ORM과 함께 부활하려는 구체적인 패러다임의 구현체가 DDD+CQRS 이며,  개발문화의 변화및 수준높은 개발능력을 요구합니다. "ddd cqrs orm" 키워드로 검색을 해보면  꽤 높은수준의 DB 이해와 OOP활용 능력이 요구됨을 알수 있다.
정리: