[꼼꼼한 개발자] 꼼코더

45. 코드로 배우는 스프링 웹 프로젝트 - [페이징 처리] - 페이지 번호 1,2의 데이터, 인라인 뷰(In-ine View) 처리 본문

Spring/코드로 배우는 스프링 웹 프로젝트

45. 코드로 배우는 스프링 웹 프로젝트 - [페이징 처리] - 페이지 번호 1,2의 데이터, 인라인 뷰(In-ine View) 처리

꼼코더 2023. 1. 28. 22:06
반응형
 

🔍 페이지 번호 1,2의 데이터

한 페이지당 10개의 데이터를 출력한다고 가정하고

ROWNUM 조건을 WHERE 구문에 추가하여 다음과 같이 작성할 수 있다.

/* tbl_board 테이블을 bno의 역순으로 접근 후 한 페이지당 10개의 데이터를 출력(힌트 사용) /
select /+ INDEX_DESC(tbl_board pk_board) */
rownum rn, bno, title, content from tbl_board
where rownum <= 10;
 
 

SQL의 실행결과를 보면 가장 높은 번호의 게시물 10개만 출력되는 것을 볼 수 있다

이때 실행 계획을 통해 PK_BOARD 인덱스를 역순으로 접근하는 것을 확인할 수 있다.

 

WHERE 조건에서 특이하게 ROWNUM 조건은

테이블을 접근할 때 필터링 조건을 적용된 것을 볼 수 있다.

 

1페이지 데이터를 구해봤다 동일한 방식으로 2페이지 데이터를 구해보자

/* tbl_board 테이블을 bno의 역순으로 접근 후 2 페이지의 10개의 데이터를 출력(힌트 사용) */
select /*+ INDEX_DESC(tbl_board pk_board) */
rownum rn, bno, title, content from tbl_board
where rownum > 10 and rownum <= 20;
 

하지만 원하는 결과를 구할 수 없다.

그 원인을 알아보자..

 

SQL을 보면 10보다 크고 20보다 작거나

같은 데이터들을 가져올 것이라고 기대하지만 실제로 아무 결과가 나오지 않는다

이렇게 되는 이유를 알아내려면 실행 계획을 유심히 살펴봐야 한다.

 

 

실행 계획을 위에서부터 아래로 보게 되므로

우선 ROWNUM > 10 데이터들을 찾게 된다.

 

문제는 TBL_BOARD에 처음으로 나오는 ROWNUM의 값이 1이라는 것이다.

TBL_BOARD에서 데이터를 찾고 ROWNUM 값이 1이 된 데이터는

where 조건에 의해서 무효화된다.( > 10)

 

이후 다시 다른 데이터를 가져오면 새로운 데이터가 첫 번째 데이터가 되므로

다시 ROWNUM은 1이 된다. (위 상황 반복)

 

이러한 이유로 SQL 작성 시 ROWNUM 조건은 반드시 1이 포함되어야 한다.

SQL에 ROWNUM 조건이 1이 포함되도록 다음과 같이 수정해 주자

 

/* tbl_board 테이블을 bno의 역순으로 접근 후
 페이지 2의 10개의 데이터를 출력(힌트 사용) 
	ROWNUM은 반드시 1이 포함되도록 해야한다 */
select /*+ INDEX_DESC(tbl_board pk_board) */
rownum rn, bno, title, content from tbl_board
where rownum <= 20;

달라진 점은 rownum 조건이 1을 포함하도록 변경한 것뿐이다(조건문만 수정)

결과는 데이터를 20개 가져오게 된다.


🛼인라인 뷰(In-ine View) 처리

10개씩 목록을 출력하는 경우 2페이지의 데이터 20개를 가져오는 데 성공하였지만

1페이지 내용이 같이 출력되는 문제가 있으므로 마지막으로 이 문제를 수정해야 한다.

 

문제를 해결하려면 인라인뷰라는 것을 이용해야 하는데

쉽게 설명하자면 ‘SELECT문 안쪽 FROM에 다시 SELECT문’으로 이해할 수 있다.

 

인라인뷰는 논리적으로는 어떤 결과를 구하는 SELECET문이 있고

그 결과를 다시 대상으로 삼아서 SELECT 하는 것이다.

 

데이터베이스에서는 테이블이나 인덱스와 같이 뷰(View)라는 개념이 존재한다.

 

‘뷰(View)’는 일종의 ‘창문’ 같은 개념으로 복잡한 SELECT 처리를 하나의 뷰로 생성하고

사용자들은 뷰를 통해서 복잡하게 만들어진 결과를 마치 하나의 테이블처럼 쉽게 조회한다는 개념이다.

 

 

외부 SELECT문은 인라인뷰로 작성된 결과를 마치 하나의 테이블 처럼 사용한다.

예시로 이전(위) 결과를 보면 20개의 데이터를 가져오는 SQL을

하나의 테이블로(레코드가 20개인) 간주하고 바깥쪽에서 그 테이블 기준으로 추가적인 처리를 하는 것이다.

select * from(
(
select /*+ INDEX_DESC(tbl_board pk_board) */
rownum rn, bno, title, content from tbl_board
where rownum <= 20
);

 

 
 

만일 결과를 테이블로 보다면 칼럼을 가져야 하기 때문에 칼럼을 지정해 주고

원하는 RN 칼럽 값은 10보다 큰 데이터만 가져오면 되기 때문에 조건도 작성해 주어

인라인뷰 처리를 해준다.

select bno, title, content
from (
	select /*+ INDEX_DESC(tbl_board pk_board) */
	rownum rn, bno, title, content from tbl_board
	where rownum <= 20
)
where rn > 10;

 

2페이지에 해당하는 10개만 추출하는 방식으로 구현을 했다.

2페이지에 해당하는 10개만 추출하는 방식으로 구현을 했다.


🧹 과정 총 정리

필요한 순서로 정렬된 데이터에 ROWNUM을 붙인다.

처음부터 해당 페이지의 데이터를 ‘ROWNUM <= 30’과 같은 조건을 이용해서 구한다.

구해놓은 데이터를 하나의 테이블처럼 간주하고 인라인뷰로 처리한다.

인라인뷰에서 필요한 데이터만을 남긴다.

 

 

 

 

 

 
Comments