본문 바로가기

프로젝트/KimsBoard

DML(2) 어떤 것을 참고 하여 DML쿼리를 작성해야 하나? VIEW작성?

"게시물 작성" 에서는 API명세서보다는 게시물 작성시 board테이블안에 하나의 board인스턴스가 생성되는 것이기 때문에 데이터베이스의 DDL을 보고 DML를 구성해 주었다. 하지만 게시물 상세 같은 경우는 DDL의 특정 테이블을 보는 것이 아닌 클라이언트가 서버로부터 Response받는 내용물들에 모든 정보가 있는 것이니 API명세서를 보는 것이다. RESPONSE의 내용은 아래와 같다. 따라서 이러한 내용들을 얻을 수 있게 DML을 구성해 주어야 하고 board와 user테이블을 조인하면 아래의 데이터들을 얻을 수 있다.

다만 '게시물 이미지 리스트' 같은 경우는 user와 board테이블을 조인해도 얻을 수 없으니 image테이블에서 별도로 가져 온 것이 '상세 게시물 불러오기'의 DML쿼리 였다.

======================================================================================

'게시물 상세'가 아닌 '게시물의 리스트' 를 불러올때는 Response로 받는 데이터가 다르다. 하지만 다양한 종류의 게시물 리스트가 있는데(검색 게시물 리스트, 특정 유저 게시물 리스트, 최신 게시물 리스트 등등) Response로 받는 데이터는 조금씩 달라도 여러 종류의 게시물 리스트를 받아오는게 필요하다면 어디서나 쓰이는 DML은 아래와 같다(대동소이함)

========================================================================================

3개의 테이블을 조인하여 '최신 게시물 불러오기' DML 쿼리 짜기

아직 익숙하지 않은 것 중에 3개의 테이블을 조인하는 ANSI문법이란 것이 있다. 기존에 알고 있던 테이블 먼저 FROM절에 join(조인)과 연관된 테이블들을 적어주고 나머지는 ON에서 처리하는 것을 ORACLE문법이라하고 아래와 같이 ON과 JOIN을 번갈아 써주는 것을 ANSI문법이라 한다 (참고: https://blog.naver.com/PostView.nhn?blogId=regenesis90&logNo=222190687396 )

 

영상: 6:47  https://www.youtube.com/watch?v=-cvkyK32q94&list=PLbq5jHjpmq7q-Td2jOXtpf7SD5c53RqXh&index=7 )

여기서 잠깐!!!

왜 그냥 편하게

1)

이렇게 하지않고

GROUP BY를 사용하여 아래와 같이 해주었나?

2)

중복을 제거하기 위함이다. 1)과 같이 하면 그 결과로

board_number의 값이 1인 튜플이 2개 출력되지만 GROUP BY를 사용하면 아래와 같이 중복이 제거된다.

 

이후 SELECT를 더 다듬고 ORDER BY, LIMIT 5,5를 적용하여 "최신 게시물 리스트"를 불러오는 쿼리를 완성한다. 다만 여기서 한가지 기억할것이 LIMIT a,b 하면 a-1부터 b개의 행이 출력되는데 LIMIT이 잘 동작하지 않을 때가 있는데 왜 그런지는 잘 모르겠다.

--최신게시물 리스트 불러오기
SELECT B.board_number AS board_number,
B.title AS title,
B.content AS content,
I.image as titleImage,
B.favorite_count AS favorite_count,
B.comment_count AS comment_count,
B.view_count AS view_count,
B.write_datetime AS write_datetime,
U.nickname AS writer_nickname,
U.profile_image AS writer_profile_image
FROM board AS B INNER JOIN user AS U -- board테이블이 기준이 되어 나머지 2개의 테이블과 조인됨
ON U.email=B.writerEmail
LEFT OUTER JOIN (SELECT board_number, ANY_VALUE(image) AS image FROM image GROUP BY board_number)AS I
ON B.board_number=I.board_number
ORDER BY write_datetime
LIMIT 3,3;

 

=================================================================================

4종류의 게시물 불러오기인 최신 게시물 리스트, 검색어 리스트, 주간 상위3 게시물 리스트, 특정유저 게시물 리스트 불러오기 모두가 on구문 까지는 똑같다. 따라서 이렇게 중복하지 않고 VIEW를 사용하여 중복을 제거할 수 있다. DDL에 VIEW를 작성해 준다.

CREATE VIEW board_list_view AS
SELECT 
B.board_number AS board_number,
B.title AS title,
B.content AS content,
I.image as titleImage,
B.favorite_count AS favorite_count,
B.comment_count AS comment_count,
B.view_count AS view_count,
B.write_datetime AS write_datetime,
B.writerEmail as writer_email,
U.nickname AS writer_nickname,
U.profile_image AS writer_profile_image
FROM board AS B INNER JOIN user AS U -- board테이블이 기준이 되어 나머지 2개의 테이블과 조인됨
ON U.email=B.writerEmail 
LEFT OUTER JOIN (SELECT board_number, ANY_VALUE(image) AS image FROM image GROUP BY board_number)AS I
ON B.board_number=I.board_number

이후 board_list_view라는 VIEW를 적용한 코드는 아래와 같다. 전체 예시는 KimsBoard의 MySQL의 DML을 참고.

SELECT *
FROM board_list_view
WHERE title like "%제목%" or content like "%제목%"
ORDER BY write_datetime DESC
LIMIT 3,3;